Python PyQt5 实现桌面动态宠物:从素材导入到交互逻辑完整教程
本文详细介绍如何使用 Python 和 PyQt5 框架开发一个桌面动态宠物小程序。内容涵盖 GUI 窗口初始化与透明背景设置、本地素材图片的批量导入与 QImage 处理、基于 QTimer 的图片随机切换动画实现,以及通过多线程和标志位控制宠物的上下移动、停止、睡觉和退出等交互功能。
本文将分享一个基于 Python 和 PyQt5 框架开发的桌面宠物小程序。对于希望深入探索 Python GUI 编程的开发者而言,这是一个值得参考的实战案例。
首先展示最终运行效果。作为一个轻量级的娱乐项目,该桌面宠物在视觉表现上具有一定的趣味性。

本文的设计灵感及部分核心代码参考自知乎平台的一篇文章,有兴趣的读者可通过链接[1]查阅原始来源。
接下来直接进入技术实现部分。本项目采用 PYQT5 作为核心编码框架,若读者对该框架尚不熟悉,建议先进行基础学习。
获取素材图片
关于素材图片的来源,本文使用了一款名为 shimeji 的国外应用程序。读者可自行下载体验以获取相关资源。

作者已整理好部分素材图片,如需使用,可在文章末尾获取下载方式。
窗体设置
第一步是初始化 GUI 窗口。
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
class DesktopPet(QWidget):
tool_name = '桌面宠物'
def __init__(self, parent=None, **kwargs):
super(DesktopPet, self).__init__(parent)
self.index = 0
self.show()
由于桌面宠物仅需展示图片素材部分,因此需要对 GUI 窗口进行特定的属性配置。
# 含义分别是设置窗口无边框,窗口始终处于顶层位置,窗口无按钮
self.setWindowFlags(Qt.FramelessWindowHint|Qt.WindowStaysOnTopHint|Qt.SubWindow)
self.setAutoFillBackground(False)
self.setAttribute(Qt.WA_TranslucentBackground, True)
self.repaint()
self.resize(128, 128)
随后,导入一张测试图片以验证窗口显示效果。
# 导入宠物
image = QImage()
image.load(os.path.join("resources", "30", 'shime1.png'))
self.image = QLabel(self)
self.setImage(image)
self.show()
运行效果如下:

此时,一个静态的简易宠物图像已出现在屏幕上。后续工作是将所有下载的素材图片导入,并实现随机展示功能。
随机展示宠物图片
首先编写一个用于导入图片的函数。
"""导入图像"""
def loadImage(self, imagepath):
image = QImage()
image.load(imagepath)
return image
该函数的功能是将本地图片文件加载并转换为 QImage 类型。
接着,编写一个用于导入全部图片素材的函数。
def loadPetImages(self):
actions = self.action_distribution
pet_images = []
for action in actions:
pet_images.append(
[self.loadImage(os.path.join("resources", "30", 'shime' + item + '.png')) for item in action])
iconpath = os.path.join("resources", "30", 'shime1.png')
return pet_images, iconpath
在类的初始化函数中调用上述素材导入函数即可。
# 导入宠物
self.pet_images, iconpath = self.loadPetImages()
self.image = QLabel(self)
self.setImage(self.pet_images[0][0])
至此,30文件夹下的所有素材图片均被成功导入,并将第一张图片设置为初始显示状态。
添加动作
一个完整的桌面宠物必须具备动态行为,否则缺乏互动性。
本例中定义的动作主要分为两类。
- 图片切换
- 上下移动
首先处理图片切换逻辑,定义一个动作函数。
def randomAct(self):
self.pet_images, iconpath = self.loadPetImages()
if not self.is_running_action:
self.is_running_action = True
self.action_images = random.choice(self.pet_images)
self.action_max_len = len(self.action_images)
self.action_pointer = 0
self.runFrame()
def runFrame(self):
if self.action_pointer == self.action_max_len:
self.is_running_action = False
self.action_pointer = 0
self.action_max_len = 0
self.setImage(self.action_images[self.action_pointer])
self.action_pointer += 1
上述代码实现了从素材库中随机选取图片进行切换,从而产生宠物“动起来”的视觉效果。
同时需要设置图片切换的时间间隔,避免切换速度过快影响观感。
"""普通动作"""
def commonAction(self):
# 每隔一段时间做个动作
self.timer_common = QTimer()
self.timer_common.timeout.connect(self.randomAct)
self.timer_common.start(500)
接下来处理上下移动逻辑。
对于上下移动,需计算当前窗口的位置坐标,并在规定时间内施加位移量。关键在于严格控制在屏幕上下边界内,防止宠物移出可视区域。
"""上下移动"""
def selfMoveAction(self):
try:
if self.flag_up:
if self.pos().y() - self.pet_geo_height/2 > -70:
self.move(QPoint(self.position.x(), self.position.y()-5))
self.position = QPoint(self.position.x(), self.position.y()-5)
else:
self.flag_up = False
elif not self.flag_up:
if self.pos().y() + self.pet_geo_height/2 < 700:
self.move(QPoint(self.position.x(), self.position.y() + 50))
self.position = QPoint(self.position.x(), self.position.y() + 50)
else:
self.flag_up = True
except Exception as e:
print(e)
右键菜单
为该桌面宠物定义了四个右键菜单选项,分别对应移动、停止、睡觉和退出功能。
"""右键菜单函数"""
def rightMenu(self):
self.myMenu = QMenu(self)
self.actionA = QAction(QIcon("移动"), "移动", self)
self.actionA.triggered.connect(self.moveUpDown)
self.actionB = QAction(QIcon("停止"), "停止", self)
self.actionB.triggered.connect(self.moveStop)
self.actionC = QAction(QIcon("睡觉"), "睡觉", self)
self.actionC.triggered.connect(self.moveSleep)
self.actionD = QAction(QIcon("退出"), "退出", self)
self.actionD.triggered.connect(self.quit)
self.myMenu.addAction(self.actionA)
self.myMenu.addAction(self.actionB)
self.myMenu.addAction(self.actionC)
self.myMenu.addAction(self.actionD)
self.myMenu.popup(QCursor.pos())
右键菜单绑定的动作函数定义如下。
def moveUpDown(self):
self.move_timer.start(100)
self.up_down = True
self.timer_common.start(500)
self.timer_sleep.stop()
当用户点击对应的菜单项时,系统将对应的标志位设置为True。
此外,在进行移动状态判断时,必须采用多线程方式处理。
"""多线程,判断是否上下移动"""
def upAndDown(self):
if self.up_down:
self.stop_threads = False
t = Thread(target=self.do, args={})
t.start()
else:
self.stop_threads = True
以上为主要代码逻辑,感兴趣的开发者可自行尝试运行。
至此,关于基于 Python 制作桌面宠物的介绍结束。如需了解更多 Python 桌面宠物相关内容,请搜索本站历史文章或继续浏览后续文章,感谢支持。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









