用 Python 制作一個桌面寵物,好玩!


今天,我們來分享一個寵物桌面小程序,全程都是通過 PyQT 來制作的,對于 Python GUI 感興趣的朋友,千萬不要錯過哦!
我們先來看看最終的效果,對于一個小小的娛樂項目來說,還是不錯啦!
本文靈感和部分代碼來源于一篇知乎文章,感興趣的朋友可以訪問如下鏈接[1]
好了,廢話不多說,我直接上干貨,本項目使用 PYQT5 作為編碼框架,如果你對于該框架不是特別熟悉的話,建議先去簡單學(xué)習(xí)一下~
獲取素材圖片
對于素材圖片,我這里也是使用的一款國外的 APP,叫做 shimeji,感興趣的朋友可以下載體驗下。

蘿卜哥已經(jīng)下載好了很多素材,如果需要,文末有獲取方式
窗體設(shè)置
首先我們先初始化一個 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 窗體進(jìn)行屬性設(shè)置
# 含義分別是設(shè)置窗口無邊框,窗口始終處于頂層位置,窗口無按鈕
self.setWindowFlags(Qt.FramelessWindowHint|Qt.WindowStaysOnTopHint|Qt.SubWindow)
self.setAutoFillBackground(False)
self.setAttribute(Qt.WA_TranslucentBackground, True)
self.repaint()
self.resize(128, 128)
接下來我們導(dǎo)入一個圖片,查看效果
# 導(dǎo)入寵物
image = QImage()
image.load(os.path.join("resources", "30", 'shime1.png'))
self.image = QLabel(self)
self.setImage(image)
self.show()
效果如下:

可以看到,一個簡易的不會動的寵物已經(jīng)出現(xiàn)了,后面的工作就是把下載好的所有素材全部導(dǎo)入,并隨機展示即可
隨機展示寵物圖片
我們先編寫一個導(dǎo)入圖片的函數(shù)
"""導(dǎo)入圖像"""
def loadImage(self, imagepath):
image = QImage()
image.load(imagepath)
return image
該函數(shù)可以將本地的圖片,導(dǎo)入為 QImage 類型
接下來再編寫一個導(dǎo)入全部圖片素材的函數(shù)
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
然后我們在初始化函數(shù)中調(diào)用該函數(shù)即可
# 導(dǎo)入寵物
self.pet_images, iconpath = self.loadPetImages()
self.image = QLabel(self)
self.setImage(self.pet_images[0][0])
這樣,我們就把文件夾30下面的所有素材圖片都導(dǎo)入了,并且設(shè)置第一張圖片為開始的圖片
添加動作
對于一個桌面寵物來說,沒有都做怎么能行呢
這里的動作分為兩種
圖片切換 上下移動
我們先來看圖片切換,先定義一個動作函數(shù)
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
上面的代碼就是隨機選取素材圖片切換,這樣就達(dá)到了讓寵物“動起來”的效果了
當(dāng)然還需要設(shè)置一個間隔時間,不要使得圖片切換的太快
"""普通動作"""
def commonAction(self):
# 每隔一段時間做個動作
self.timer_common = QTimer()
self.timer_common.timeout.connect(self.randomAct)
self.timer_common.start(500)
再來看看上下移動
對于上下移動,我們需要計算當(dāng)前窗體所在位置,然后一段時間給予一定的位移量,此時只需要注意好控制上下邊界,不要讓圖片移動出屏幕
"""上下移動"""
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)
右鍵菜單
對于該桌面寵物,我們還定義了四個右鍵菜單,分別為移動、停止、睡覺,退出
"""右鍵菜單函數(shù)"""
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())
對于右鍵菜單綁定的動作函數(shù),定義如下
def moveUpDown(self):
self.move_timer.start(100)
self.up_down = True
self.timer_common.start(500)
self.timer_sleep.stop()
當(dāng)點擊對應(yīng)的菜單項時,則把對應(yīng)的標(biāo)志位設(shè)置為True
這里還需要注意一點是,在進(jìn)行移動判斷的時候,需要以多線程的方式
"""多線程,判斷是否上下移動"""
def upAndDown(self):
if self.up_down:
self.stop_threads = False
t = Thread(target=self.do, args={})
t.start()
else:
self.stop_threads = True
OK,以上就是主要代碼,感興趣的小伙伴可以自行嘗試一下哦
如果需要素材圖片,可以在公眾號后臺回復(fù)“寵物素材”獲取,如果對于如何獲取所有的素材感興趣,就點個在看哈,數(shù)量足夠多,咱們下期就分享!
好了,今天的分享就到這里,喜歡就點個贊吧~
參考資料
知乎資料: https://zhuanlan.zhihu.com/p/125693970。
推薦閱讀:
入門: 最全的零基礎(chǔ)學(xué)Python的問題 | 零基礎(chǔ)學(xué)了8個月的Python | 實戰(zhàn)項目 |學(xué)Python就是這條捷徑
干貨:爬取豆瓣短評,電影《后來的我們》 | 38年NBA最佳球員分析 | 從萬眾期待到口碑撲街!唐探3令人失望 | 笑看新倚天屠龍記 | 燈謎答題王 |用Python做個海量小姐姐素描圖 |碟中諜這么火,我用機器學(xué)習(xí)做個迷你推薦系統(tǒng)電影
趣味:彈球游戲 | 九宮格 | 漂亮的花 | 兩百行Python《天天酷跑》游戲!
AI: 會做詩的機器人 | 給圖片上色 | 預(yù)測收入 | 碟中諜這么火,我用機器學(xué)習(xí)做個迷你推薦系統(tǒng)電影
小工具: Pdf轉(zhuǎn)Word,輕松搞定表格和水?。?/a> | 一鍵把html網(wǎng)頁保存為pdf!| 再見PDF提取收費! | 用90行代碼打造最強PDF轉(zhuǎn)換器,word、PPT、excel、markdown、html一鍵轉(zhuǎn)換 | 制作一款釘釘?shù)蛢r機票提示器! |60行代碼做了一個語音壁紙切換器天天看小姐姐!|
年度爆款文案
點閱讀原文,看B站50個Python實戰(zhàn)視頻!
