桌面宠物素材

1. 须要筹备什么素材

桌面宠物的各种动画成果,能够看作是由一个个GIF动图拼接而成,咱们须要筹备多组GIF动图来实现桌面宠物的动作切换。

最好选取是白底的GIF动图。

2. 介绍几种取得GIF动图的形式

2.1 通过pr实现视频转GIF

pr在导出的时候抉择动画GIF能够间接导出GIF动图。

当然了想要白底就须要自已用“蒙版”和画笔工具本人抠图了。

2.2 通过ps实现图片组转GIF

ps会高级一点,首先点击最上方的窗口,再点击时间轴,在下方显示出的时间轴的最左边的加号能够增加你想要增加的图片。图层左边能够抉择删除背景。

而后抉择最上方的文件,抉择导出,抉择导出为web所用格局旧版,即可

2.3 百度一下,获取网上现成的GIF资源

① 百度:“制作GIF动图”

② 百度    “GIF动图资源”

python实现代码

1 目录构造

我的项目的目录构造整体如下:main.py为主程序代码。

normal下的GIF图是宠物平时会随机切换的动作GIF图, click上面的GIF图是点击宠物之后的宠物动作的GIF图

dialog.txt 记录了宠物的对话信息

tigerIcon.jpg是放大到托盘后托盘图标的图片

2 实现代码

2.1 援用包

os包用于加载文件,sys包用于退出程序,random包用于程序中一些须要调用随机数的操作。其余的三个包则是用于实现桌面宠物的根底。

import osimport sysimport randomfrom PyQt5.QtGui import *from PyQt5.QtCore import *from PyQt5.QtWidgets import *

2.2 主代码局部

if __name__ == '__main__':    # 创立了一个QApplication对象,对象名为app,带两个参数argc,argv    # 所有的PyQt5利用必须创立一个利用(Application)对象。sys.argv参数是一个来自命令行的参数列表。    app = QApplication(sys.argv)    # 窗口组件初始化    pet = DesktopPet()    # 1. 进入工夫循环;    # 2. wait,直到响应app可能的输出;    # 3. QT接管和解决用户及零碎交代的事件(音讯),并传递到各个窗口;    # 4. 程序遇到exit()退出时,机会返回exec()的值。    sys.exit(app.exec_())

2.3 代码运行流程

整个运行流程为:

(1)通过self.init():实现窗体的初始化,宠物的GIF图在这个窗体中播放。

(2)通过self.initPall():配置托盘化

(3)通过self.initPetImage():将宠物的动态GIF资源,包含对话和GIF动图进行加载

(4)通过self.petNormalAction():实现宠物随机切换动作和语句的性能

class DesktopPet(QWidget):    def __init__(self, parent=None, **kwargs):        super(DesktopPet, self).__init__(parent)        # 窗体初始化        self.init()        # 托盘化初始        self.initPall()        # 宠物动态gif图加载        self.initPetImage()        # 宠物失常待机,实现随机切换动作        self.petNormalAction()

① 加载显示GIF动图的窗体,通过函数init实现,其代码配置如下:

这几句的作用是对展现宠物的窗体进行一些初步的设置,使得红色GIF图可能去掉背景的红色,将GIF图通明的展现进去

    # 窗体初始化    def init(self):        # 初始化        # 设置窗口属性:窗口无标题栏且固定在最后面        # FrameWindowHint:无边框窗口        # WindowStaysOnTopHint: 窗口总显示在最下面        # SubWindow: 新窗口部件是一个子窗口,而无论窗口部件是否有父窗口部件        # https://blog.csdn.net/kaida1234/article/details/79863146        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow)        # setAutoFillBackground(True)示意的是主动填充背景,False为通明背景        self.setAutoFillBackground(False)        # 窗口通明,窗体空间不通明        self.setAttribute(Qt.WA_TranslucentBackground, True)        # 重绘组件、刷新        self.repaint()

② 实现能托盘显示的性能,通过函数initPall实现,其代码配置如下:

次要有上面这几个操作:

(1)读取动态图片资源设置托盘化的图标

(2)设置托盘化图片点击右键显示的菜单,并对这些菜单的点击操作进行设置

流程代码如下: 

 # 托盘化设置初始化    def initPall(self):        # 导入筹备在托盘化显示上应用的图标        icons = os.path.join('tigerIcon.jpg')        # 设置右键显示最小化的菜单项        # 菜单项退出,点击后调用quit函数        quit_action = QAction('退出', self, triggered=self.quit)        # 设置这个点击选项的图片        quit_action.setIcon(QIcon(icons))        # 菜单项显示,点击后调用showing函数        showing = QAction(u'显示', self, triggered=self.showwin)        # 新建一个菜单项控件        self.tray_icon_menu = QMenu(self)        # 在菜单栏增加一个无子菜单的菜单项‘退出’        self.tray_icon_menu.addAction(quit_action)        # 在菜单栏增加一个无子菜单的菜单项‘显示’        self.tray_icon_menu.addAction(showing)        # QSystemTrayIcon类为应用程序在系统托盘中提供一个图标        self.tray_icon = QSystemTrayIcon(self)        # 设置托盘化图标        self.tray_icon.setIcon(QIcon(icons))        # 设置托盘化菜单项        self.tray_icon.setContextMenu(self.tray_icon_menu)        # 展现        self.tray_icon.show()

其中‘退出’项波及到的函数代码如下:

    # 退出操作,关闭程序    def quit(self):        self.close()        sys.exit()

其中‘显示’项波及到的函数代码如下:

    # 显示宠物    def showwin(self):        # setWindowOpacity()设置窗体的透明度,通过调整窗体透明度实现宠物的展现和暗藏        self.setWindowOpacity(1)

③ 宠物动态资源的加载,通过函数initPetImage实现,其代码配置如下:

动态资源的加载次要波及两个局部,对话框内容的加载和图片内容的加载。

    # 宠物动态gif图加载    def initPetImage(self):        # 对话框定义        self.talkLabel = QLabel(self)        # 对话框款式设计        self.talkLabel.setStyleSheet("font:15pt '楷体';border-width: 1px;color:blue;")         # 定义显示图片局部        self.image = QLabel(self)        # QMovie是一个能够寄存动静视频的类,个别是配合QLabel应用的,能够用来寄存GIF动态图        self.movie = QMovie("normal/normal1.gif")        # 设置标签大小        self.movie.setScaledSize(QSize(200, 200))        # 将Qmovie在定义的image中显示        self.image.setMovie(self.movie)        self.movie.start()        self.resize(1024, 1024)        # 调用自定义的randomPosition,会使得宠物呈现地位随机        self.randomPosition()        # 展现        self.show()        # https://new.qq.com/rain/a/20211014a002rs00        # 将宠物失常待机状态的动图放入pet1中        self.pet1 = []        for i in os.listdir("normal"):            self.pet1.append("normal/" + i)        # 将宠物失常待机状态的对话放入pet2中        self.dialog = []        # 读取目录下dialog文件        with open("dialog.txt", "r") as f:            text = f.read()            # 以\n 即换行符为分隔符,宰割放进dialog中            self.dialog = text.split("\n")

其中咱们心愿宠物呈现的地位是随机的而不是固定的,那么便通过 randomPosition()实现宠物呈现地位的随机。

    # 宠物随机地位    def randomPosition(self):        # screenGeometry()函数提供无关可用屏幕几何的信息        screen_geo = QDesktopWidget().screenGeometry()        # 获取窗口坐标系        pet_geo = self.geometry()        width = (screen_geo.width() - pet_geo.width()) * random.random()        height = (screen_geo.height() - pet_geo.height()) * random.random()        self.move(width, height)

④ 宠物失常待机,实现随机切换动作,对话框通过函数petNormalAction实现,其代码配置如下

这里通过QTimer实现定时操作,达到设置的工夫即调用相干的函数。其中condition为标识宠物状态的flag,0为平时状态,1为点击状态,这个状态可依照本人的爱好拓展。talk_condition同理,为标识宠物对话状态的flag。

# 宠物失常待机动作    def petNormalAction(self):        # 每隔一段时间做个动作        # 定时器设置        self.timer = QTimer()        # 工夫到了主动执行        self.timer.timeout.connect(self.randomAct)        # 动作工夫切换设置        self.timer.start(3000)        # 宠物状态设置为失常        self.condition = 0        # 每隔一段时间切换对话        self.talkTimer = QTimer()        self.talkTimer.timeout.connect(self.talk)        self.talkTimer.start(3000)        # 对话状态设置为常态        self.talk_condition = 0        # 宠物对话框        self.talk()

其中,通过randomAct实现宠物动作的随机切换,通过talk实现对话框内容的切换,其代码如下:

self.pet1和self.dialog在初始化的时候即定义了。这里能够依照本人的爱好进行拓展,用多个if-else if实现多种状态的切换和定义,减少一些喂食,游玩动作等。

 # 随机动作切换    def randomAct(self):        # condition记录宠物状态,宠物状态为0时,代表失常待机        if not self.condition:            # 随机抉择装载在pet1外面的gif图进行展现,实现随机切换            self.movie = QMovie(random.choice(self.pet1))            # 宠物大小            self.movie.setScaledSize(QSize(200, 200))            # 将动画增加到label中            self.image.setMovie(self.movie)            # 开始播放动画            self.movie.start()        # condition不为0,转为切换特有的动作,实现宠物的点击反馈        # 这里能够通过else-if语句往下拓展做更多的交互性能        else:            # 读取非凡状态图片门路            self.movie = QMovie("./click/click.gif")            # 宠物大小            self.movie.setScaledSize(QSize(200, 200))            # 将动画增加到label中            self.image.setMovie(self.movie)            # 开始播放动画            self.movie.start()            # 宠物状态设置为失常待机            self.condition = 0            self.talk_condition = 0     # 宠物对话框行为解决    def talk(self):        if not self.talk_condition:            # talk_condition为0则选取加载在dialog中的语句            self.talkLabel.setText(random.choice(self.dialog))            # 设置款式            self.talkLabel.setStyleSheet(                "font: bold;"                "font:25pt '楷体';"                "color:white;"                "background-color: white"                "url(:/)"            )            # 依据内容自适应大小            self.talkLabel.adjustSize()        else:            # talk_condition为1显示为别点我,这里同样能够通过if-else-if来拓展对应的行为            self.talkLabel.setText("别点我")            self.talkLabel.setStyleSheet(                "font: bold;"                "font:25pt '楷体';"                "color:white;"                "background-color: white"                "url(:/)"            )            self.talkLabel.adjustSize()            # 设置为失常状态            self.talk_condition = 0

⑤ 实现可能拖动宠物,通过多个自带函数实现,其代码配置如下:

实现宠物的拖动次要通过三个函数实现,mouserPressEvent负责在鼠标点击判断其是否在宠物窗口上,如果在则将宠物和鼠标的地位绑定,并执行点击扭转宠物GIF图和对话框的操作。

mouseMoveEvent实现按下后宠物跟着鼠标挪动

mouseReleaseEvent将之前的锁定勾销

 # 鼠标左键按下时, 宠物将和鼠标地位绑定    def mousePressEvent(self, event):        # 更改宠物状态为点击        self.condition = 1        # 更改宠物对话状态        self.talk_condition = 1        # 即可调用对话状态扭转        self.talk()        # 即刻加载宠物点击动画        self.randomAct()        if event.button() == Qt.LeftButton:            self.is_follow_mouse = True        # globalPos() 事件触发点绝对于桌面的地位        # pos() 程序绝对于桌面左上角的地位,理论是窗口的左上角坐标        self.mouse_drag_pos = event.globalPos() - self.pos()        event.accept()        # 拖动时鼠标图形的设置        self.setCursor(QCursor(Qt.OpenHandCursor))     # 鼠标挪动时调用,实现宠物随鼠标挪动    def mouseMoveEvent(self, event):        # 如果鼠标左键按下,且处于绑定状态        if Qt.LeftButton and self.is_follow_mouse:            # 宠物随鼠标进行挪动            self.move(event.globalPos() - self.mouse_drag_pos)        event.accept()     # 鼠标开释调用,勾销绑定    def mouseReleaseEvent(self, event):        self.is_follow_mouse = False        # 鼠标图形设置为箭头        self.setCursor(QCursor(Qt.ArrowCursor))

⑥ 实现宠物右键点击具备交互性能,通过函数contextMenuEvent实现,其代码配置如下:

退出操作通过 qApp.quit()实现,间接退出相应的QT程序。

暗藏操作则通过self.setWindowOpacity(0)实现,这个可管制窗口的透明度。

 # 宠物右键点击交互    def contextMenuEvent(self, event):        # 定义菜单        menu = QMenu(self)        # 定义菜单项        quitAction = menu.addAction("退出")        hide = menu.addAction("暗藏")        # 应用exec_()办法显示菜单。从鼠标右键事件对象中取得以后坐标。mapToGlobal()办法把以后组件的绝对坐标转换为窗口(window)的相对坐标。        action = menu.exec_(self.mapToGlobal(event.pos()))        # 点击事件为退出        if action == quitAction:            qApp.quit()        # 点击事件为暗藏        if action == hide:            # 通过设置透明度形式暗藏宠物            self.setWindowOpacity(0)

⑦ 鼠标移到宠物上的时候显示为闭合的手

    # 鼠标移进时调用    def enterEvent(self, event):        # 设置鼠标形态 Qt.ClosedHandCursor   非指向手        self.setCursor(Qt.ClosedHandCursor)

3 残缺源码

import osimport sysimport randomfrom PyQt5.QtGui import *from PyQt5.QtCore import *from PyQt5.QtWidgets import *  class DesktopPet(QWidget):    def __init__(self, parent=None, **kwargs):        super(DesktopPet, self).__init__(parent)        # 窗体初始化        self.init()        # 托盘化初始        self.initPall()        # 宠物动态gif图加载        self.initPetImage()        # 宠物失常待机,实现随机切换动作        self.petNormalAction()      # 窗体初始化    def init(self):        # 初始化        # 设置窗口属性:窗口无标题栏且固定在最后面        # FrameWindowHint:无边框窗口        # WindowStaysOnTopHint: 窗口总显示在最下面        # SubWindow: 新窗口部件是一个子窗口,而无论窗口部件是否有父窗口部件        # https://blog.csdn.net/kaida1234/article/details/79863146        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow)        # setAutoFillBackground(True)示意的是主动填充背景,False为通明背景        self.setAutoFillBackground(False)        # 窗口通明,窗体空间不通明        self.setAttribute(Qt.WA_TranslucentBackground, True)        # 重绘组件、刷新        self.repaint()     # 托盘化设置初始化    def initPall(self):        # 导入筹备在托盘化显示上应用的图标        icons = os.path.join('tigerIcon.jpg')        # 设置右键显示最小化的菜单项        # 菜单项退出,点击后调用quit函数        quit_action = QAction('退出', self, triggered=self.quit)        # 设置这个点击选项的图片        quit_action.setIcon(QIcon(icons))        # 菜单项显示,点击后调用showing函数        showing = QAction(u'显示', self, triggered=self.showwin)        # 新建一个菜单项控件        self.tray_icon_menu = QMenu(self)        # 在菜单栏增加一个无子菜单的菜单项‘退出’        self.tray_icon_menu.addAction(quit_action)        # 在菜单栏增加一个无子菜单的菜单项‘显示’        self.tray_icon_menu.addAction(showing)        # QSystemTrayIcon类为应用程序在系统托盘中提供一个图标        self.tray_icon = QSystemTrayIcon(self)        # 设置托盘化图标        self.tray_icon.setIcon(QIcon(icons))        # 设置托盘化菜单项        self.tray_icon.setContextMenu(self.tray_icon_menu)        # 展现        self.tray_icon.show()     # 宠物动态gif图加载    def initPetImage(self):        # 对话框定义        self.talkLabel = QLabel(self)        # 对话框款式设计        self.talkLabel.setStyleSheet("font:15pt '楷体';border-width: 1px;color:blue;")        # 定义显示图片局部        self.image = QLabel(self)        # QMovie是一个能够寄存动静视频的类,个别是配合QLabel应用的,能够用来寄存GIF动态图        self.movie = QMovie("normal/normal1.gif")        # 设置标签大小        self.movie.setScaledSize(QSize(200, 200))        # 将Qmovie在定义的image中显示        self.image.setMovie(self.movie)        self.movie.start()        self.resize(1024, 1024)        # 调用自定义的randomPosition,会使得宠物呈现地位随机        self.randomPosition()        # 展现        self.show()        # https://new.qq.com/rain/a/20211014a002rs00        # 将宠物失常待机状态的动图放入pet1中        self.pet1 = []        for i in os.listdir("normal"):            self.pet1.append("normal/" + i)        # 将宠物失常待机状态的对话放入pet2中        self.dialog = []        # 读取目录下dialog文件        with open("dialog.txt", "r") as f:            text = f.read()            # 以\n 即换行符为分隔符,宰割放进dialog中            self.dialog = text.split("\n")     # 宠物失常待机动作    def petNormalAction(self):        # 每隔一段时间做个动作        # 定时器设置        self.timer = QTimer()        # 工夫到了主动执行        self.timer.timeout.connect(self.randomAct)        # 动作工夫切换设置        self.timer.start(3000)        # 宠物状态设置为失常        self.condition = 0        # 每隔一段时间切换对话        self.talkTimer = QTimer()        self.talkTimer.timeout.connect(self.talk)        self.talkTimer.start(3000)        # 对话状态设置为常态        self.talk_condition = 0        # 宠物对话框        self.talk()     # 随机动作切换    def randomAct(self):        # condition记录宠物状态,宠物状态为0时,代表失常待机        if not self.condition:            # 随机抉择装载在pet1外面的gif图进行展现,实现随机切换            self.movie = QMovie(random.choice(self.pet1))            # 宠物大小            self.movie.setScaledSize(QSize(200, 200))            # 将动画增加到label中            self.image.setMovie(self.movie)            # 开始播放动画            self.movie.start()        # condition不为0,转为切换特有的动作,实现宠物的点击反馈        # 这里能够通过else-if语句往下拓展做更多的交互性能        else:            # 读取非凡状态图片门路            self.movie = QMovie("./click/click.gif")            # 宠物大小            self.movie.setScaledSize(QSize(200, 200))            # 将动画增加到label中            self.image.setMovie(self.movie)            # 开始播放动画            self.movie.start()            # 宠物状态设置为失常待机            self.condition = 0            self.talk_condition = 0     # 宠物对话框行为解决    def talk(self):        if not self.talk_condition:            # talk_condition为0则选取加载在dialog中的语句            self.talkLabel.setText(random.choice(self.dialog))            # 设置款式            self.talkLabel.setStyleSheet(                "font: bold;"                "font:25pt '楷体';"                "color:white;"                "background-color: white"                "url(:/)"            )            # 依据内容自适应大小            self.talkLabel.adjustSize()        else:            # talk_condition为1显示为别点我,这里同样能够通过if-else-if来拓展对应的行为            self.talkLabel.setText("别点我")            self.talkLabel.setStyleSheet(                "font: bold;"                "font:25pt '楷体';"                "color:white;"                "background-color: white"                "url(:/)"            )            self.talkLabel.adjustSize()            # 设置为失常状态            self.talk_condition = 0     # 退出操作,关闭程序    def quit(self):        self.close()        sys.exit()     # 显示宠物    def showwin(self):        # setWindowOpacity()设置窗体的透明度,通过调整窗体透明度实现宠物的展现和暗藏        self.setWindowOpacity(1)     # 宠物随机地位    def randomPosition(self):        screen_geo = QDesktopWidget().screenGeometry()        pet_geo = self.geometry()        width = (screen_geo.width() - pet_geo.width()) * random.random()        height = (screen_geo.height() - pet_geo.height()) * random.random()        self.move(width, height)     # 鼠标左键按下时, 宠物将和鼠标地位绑定    def mousePressEvent(self, event):        # 更改宠物状态为点击        self.condition = 1        # 更改宠物对话状态        self.talk_condition = 1        # 即可调用对话状态扭转        self.talk()        # 即刻加载宠物点击动画        self.randomAct()        if event.button() == Qt.LeftButton:            self.is_follow_mouse = True        # globalPos() 事件触发点绝对于桌面的地位        # pos() 程序绝对于桌面左上角的地位,理论是窗口的左上角坐标        self.mouse_drag_pos = event.globalPos() - self.pos()        event.accept()        # 拖动时鼠标图形的设置        self.setCursor(QCursor(Qt.OpenHandCursor))     # 鼠标挪动时调用,实现宠物随鼠标挪动    def mouseMoveEvent(self, event):        # 如果鼠标左键按下,且处于绑定状态        if Qt.LeftButton and self.is_follow_mouse:            # 宠物随鼠标进行挪动            self.move(event.globalPos() - self.mouse_drag_pos)        event.accept()     # 鼠标开释调用,勾销绑定    def mouseReleaseEvent(self, event):        self.is_follow_mouse = False        # 鼠标图形设置为箭头        self.setCursor(QCursor(Qt.ArrowCursor))      # 鼠标移进时调用    def enterEvent(self, event):        # 设置鼠标形态 Qt.ClosedHandCursor   非指向手        self.setCursor(Qt.ClosedHandCursor)     # 宠物右键点击交互    def contextMenuEvent(self, event):        # 定义菜单        menu = QMenu(self)        # 定义菜单项        quitAction = menu.addAction("退出")        hide = menu.addAction("暗藏")        # 应用exec_()办法显示菜单。从鼠标右键事件对象中取得以后坐标。mapToGlobal()办法把以后组件的绝对坐标转换为窗口(window)的相对坐标。        action = menu.exec_(self.mapToGlobal(event.pos()))        # 点击事件为退出        if action == quitAction:            qApp.quit()        # 点击事件为暗藏        if action == hide:            # 通过设置透明度形式暗藏宠物            self.setWindowOpacity(0)  if __name__ == '__main__':    # 创立了一个QApplication对象,对象名为app,带两个参数argc,argv    # 所有的PyQt5利用必须创立一个利用(Application)对象。sys.argv参数是一个来自命令行的参数列表。    app = QApplication(sys.argv)    # 窗口组件初始化    pet = DesktopPet()    # 1. 进入工夫循环;    # 2. wait,直到响应app可能的输出;    # 3. QT接管和解决用户及零碎交代的事件(音讯),并传递到各个窗口;    # 4. 程序遇到exit()退出时,机会返回exec()的值。    sys.exit(app.exec_())

程序打包

1 装置pyinstaller

pip install pyinstaller

如果提醒黄色提醒pip版本问题,照着下面的提醒批改即可

2 我的项目目录下实现打包

进入关上cmd命令行,进入我的项目目录,输出命令

pyinstaller -F -w main.py

打包实现后,在生成的dist外面能够看到main.exe文件

这里因为我本人的起因,须要将main.exe放到主目录下才可失常运行

最近我破费了几天的工夫,整顿了1份实践+实际的Python入门进阶教程,这或者是你见过十分好的一份学习材料之一。独家打造、完全免费,须要的同学能够关注gzh【Python编程学习圈】,发送“学习材料”获取~