首页 > 分享 > 桌面宠物 ① 通过python制作属于自己的桌面宠物

桌面宠物 ① 通过python制作属于自己的桌面宠物

一、桌面宠物素材

1.1 需要准备什么素材

        桌面宠物的各种动画效果,可以看作是由一个个GIF动图拼接而成,我们需要准备多组GIF动图来实现桌面宠物的动作切换。

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

1.2 介绍几种获得GIF动图的方式

1.2.1 通过pr实现视频转GIF

        pr在导出的时候选择动画GIF可以直接导出GIF动图。

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

1.2.2 通过ps实现图片组转GIF

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

        然后选择最上方的文件,选择导出,选择导出为web所用格式旧版,即可

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

① 百度:“制作GIF动图”

② 百度    “GIF动图资源”

你想要的角色人物素材都在这里!最实用的2d游戏素材! - 知乎

二、python实现代码

2.1 目录结构

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

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

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

         tigerIcon.jpg是缩小到托盘后托盘图标的图片

2.2 实现代码

2.2.1 引用包

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

import os

import sys

import random

from PyQt5.QtGui import *

from PyQt5.QtCore import *

from PyQt5.QtWidgets import *

' 2.2.2 主代码部分

if __name__ == '__main__':

app = QApplication(sys.argv)

pet = DesktopPet()

sys.exit(app.exec_())

2.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()

self.initPetImage()

self.petNormalAction()

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

        这几句的作用是对展示宠物的窗体进行一些初步的设置,使得白色GIF图能够去掉背景的白色,将GIF图透明的展示出来

def init(self):

self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow)

self.setAutoFillBackground(False)

self.setAttribute(Qt.WA_TranslucentBackground, True)

self.repaint()

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

        主要有下面这几个操作:

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

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

流程代码如下: 

def initPall(self):

icons = os.path.join('tigerIcon.jpg')

quit_action = QAction('退出', self, triggered=self.quit)

quit_action.setIcon(QIcon(icons))

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)

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):

self.setWindowOpacity(1)

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

        静态资源的加载主要涉及两个部分,对话框内容的加载和图片内容的加载。

def initPetImage(self):

self.talkLabel = QLabel(self)

self.talkLabel.setStyleSheet("font:15pt '楷体';border-width: 1px;color:blue;")

self.image = QLabel(self)

self.movie = QMovie("normal/normal1.gif")

self.movie.setScaledSize(QSize(200, 200))

self.image.setMovie(self.movie)

self.movie.start()

self.resize(1024, 1024)

self.randomPosition()

self.show()

self.pet1 = []

for i in os.listdir("normal"):

self.pet1.append("normal/" + i)

self.dialog = []

with open("dialog.txt", "r") as f:

text = f.read()

self.dialog = text.split("n")

        其中我们希望宠物出现的位置是随机的而不是固定的,那么便通过 randomPosition()实现宠物出现位置的随机。

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)

④ 宠物正常待机,实现随机切换动作,对话框通过函数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):

if not self.condition:

self.movie = QMovie(random.choice(self.pet1))

self.movie.setScaledSize(QSize(200, 200))

self.image.setMovie(self.movie)

self.movie.start()

else:

self.movie = QMovie("./click/click.gif")

self.movie.setScaledSize(QSize(200, 200))

self.image.setMovie(self.movie)

self.movie.start()

self.condition = 0

self.talk_condition = 0

def talk(self):

if not self.talk_condition:

self.talkLabel.setText(random.choice(self.dialog))

self.talkLabel.setStyleSheet(

"font: bold;"

"font:25pt '楷体';"

"color:white;"

"background-color: white"

"url(:/)"

)

self.talkLabel.adjustSize()

else:

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

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("隐藏")

action = menu.exec_(self.mapToGlobal(event.pos()))

if action == quitAction:

qApp.quit()

if action == hide:

self.setWindowOpacity(0)

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

def enterEvent(self, event):

self.setCursor(Qt.ClosedHandCursor)

2.3 完整源码

import os

import sys

import random

from 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()

self.initPetImage()

self.petNormalAction()

def init(self):

self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow)

self.setAutoFillBackground(False)

self.setAttribute(Qt.WA_TranslucentBackground, True)

self.repaint()

def initPall(self):

icons = os.path.join('tigerIcon.jpg')

quit_action = QAction('退出', self, triggered=self.quit)

quit_action.setIcon(QIcon(icons))

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)

self.tray_icon = QSystemTrayIcon(self)

self.tray_icon.setIcon(QIcon(icons))

self.tray_icon.setContextMenu(self.tray_icon_menu)

self.tray_icon.show()

def initPetImage(self):

self.talkLabel = QLabel(self)

self.talkLabel.setStyleSheet("font:15pt '楷体';border-width: 1px;color:blue;")

self.image = QLabel(self)

self.movie = QMovie("normal/normal1.gif")

self.movie.setScaledSize(QSize(200, 200))

self.image.setMovie(self.movie)

self.movie.start()

self.resize(1024, 1024)

self.randomPosition()

self.show()

self.pet1 = []

for i in os.listdir("normal"):

self.pet1.append("normal/" + i)

self.dialog = []

with open("dialog.txt", "r") as f:

text = f.read()

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):

if not self.condition:

self.movie = QMovie(random.choice(self.pet1))

self.movie.setScaledSize(QSize(200, 200))

self.image.setMovie(self.movie)

self.movie.start()

else:

self.movie = QMovie("./click/click.gif")

self.movie.setScaledSize(QSize(200, 200))

self.image.setMovie(self.movie)

self.movie.start()

self.condition = 0

self.talk_condition = 0

def talk(self):

if not self.talk_condition:

self.talkLabel.setText(random.choice(self.dialog))

self.talkLabel.setStyleSheet(

"font: bold;"

"font:25pt '楷体';"

"color:white;"

"background-color: white"

"url(:/)"

)

self.talkLabel.adjustSize()

else:

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):

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

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):

self.setCursor(Qt.ClosedHandCursor)

def contextMenuEvent(self, event):

menu = QMenu(self)

quitAction = menu.addAction("退出")

hide = menu.addAction("隐藏")

action = menu.exec_(self.mapToGlobal(event.pos()))

if action == quitAction:

qApp.quit()

if action == hide:

self.setWindowOpacity(0)

if __name__ == '__main__':

app = QApplication(sys.argv)

pet = DesktopPet()

sys.exit(app.exec_())

三、程序打包

3.1 安装pyinstaller

如果提示黄色提示pip版本问题,照着上面的提示修改即可

 3.2 项目目录下完成打包

        进入打开cmd命令行,进入项目目录,输入命令

pyinstaller -F -w main.py

         打包完成后,在生成的dist里面可以看到main.exe文件

        这里因为我自己的原因,需要将main.exe放到主目录下才可正常运行

四、总结与参考资料

4.1 项目百度网盘:

链接:https://pan.baidu.com/s/1YYXzGpmCJkz43tYuki1wFQ 
提取码:3gkw

DeskTopPetEXE为带打包好的文件。

DeskTopPet是打包前的文件。

4.2 总结

写之前挺开心的,写的时候也挺开心的,写完之后就有点索然无味了。用python做一个简单的桌面宠物,我看到的方法除了我参考的这种加载GIF图外:

Python 玩出花儿,把罗小黑养在自己桌面_AI科技大本营的博客-CSDN博客

还有一种通过加载图片帧的方式实现

Python实现桌面宠物_hxxjxw的博客-CSDN博客_python桌面宠物

这种通过图片帧的加载实现,需要编写一个自定义配置类cfg.py,很多人也不把这个东西代码给出来:

'''配置文件'''

ROOT_DIR = 'resources'

ACTION_DISTRIBUTION = [['1', '2', '3'],

['4', '5', '6', '7', '8', '9', '10', '11'],

['12', '13', '14'],

['15', '16', '17', '18']]

PET_ACTIONS_MAP = {'pet_1': ACTION_DISTRIBUTION}

for i in range(1, 4):

PET_ACTIONS_MAP.update({'pet_%s' % i: ACTION_DISTRIBUTION})

'

这种方式宠物动作的实现,是根据上面这个配置文件进行配置的,比如[1,2,3]就代表这个pet_1文件夹下对应1,2,3号图片组成一个动作。我看到有人直接把这个当作一个动作赋值给宠物,然后图片就会莫名鬼畜。

纯粹是因为无聊写着玩的,下次再试试能不能弄个3D的

相关知识

怎么用Python制作一个可以聊天的皮卡丘版桌面宠物
Python实现桌面挂件,做一只可爱的桌面宠物~
多功能宠物挂件(手机桌面宠物)
桌面宠物app下载安装
桌面宠物软件推荐 好用的桌面宠物APP排行榜
桌面宠物app哪个好 热门宠物桌面软件推荐
桌面宠物app大全
柠檬桌面宠物app下载
情侣桌面宠物app下载
桌面宠物app哪个好?手机桌面宠物软件

网址: 桌面宠物 ① 通过python制作属于自己的桌面宠物 https://m.mcbbbk.com/newsview147646.html

所属分类:萌宠日常
上一篇: [破事氵] 太喜欢收集小宠物了,
下一篇: 魔兽世界:宠物对战1