<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          寫完這段代碼,又空虛了。

          共 16808字,需瀏覽 34分鐘

           ·

          2022-05-28 14:49

          作者:林林zonzon?|?編輯:Jack?Cui?

          https://blog.csdn.net/zujiasheng/article/details/124670676

          大家好,我是 Jack。

          今天分享個(gè) Python 實(shí)戰(zhàn)小項(xiàng)目,久違的基礎(chǔ)教程!

          同時(shí),也有不少小伙伴問過我,怎么打包 Python 程序?yàn)?exe 可執(zhí)行文件,正好今天的實(shí)戰(zhàn)一起講解。

          用 Python 做個(gè)屬于自己的寵物桌面,對(duì)原理和代碼進(jìn)行了詳細(xì)講解,非常適合新手~

          一、桌面寵物素材

          1.1 需要準(zhǔn)備什么素材

          桌面寵物的各種動(dòng)畫效果,可以看作是由一個(gè)個(gè)GIF動(dòng)圖拼接而成,我們需要準(zhǔn)備多組GIF動(dòng)圖來實(shí)現(xiàn)桌面寵物的動(dòng)作切換。

          最好選取是白底的GIF動(dòng)圖。

          1.2 介紹幾種獲得GIF動(dòng)圖的方式

          1.2.1 通過pr實(shí)現(xiàn)視頻轉(zhuǎn)GIF

          pr在導(dǎo)出的時(shí)候選擇動(dòng)畫GIF可以直接導(dǎo)出GIF動(dòng)圖。

          當(dāng)然了想要白底就需要自己用“蒙版”和畫筆工具自己摳圖。

          1.2.2 通過ps實(shí)現(xiàn)圖片組轉(zhuǎn)GIF

          ps會(huì)高級(jí)一點(diǎn),首先點(diǎn)擊最上方的窗口,再點(diǎn)擊時(shí)間軸,在下方顯示出的時(shí)間軸的最右邊的加號(hào)可以添加你想要添加的圖片。圖層右邊可以選擇刪除背景。

          然后選擇最上方的文件,選擇導(dǎo)出,選擇導(dǎo)出為web所用格式舊版,即可。

          1.2.3 百度一下,獲取網(wǎng)上現(xiàn)成的GIF資源

          1)百度:“制作GIF動(dòng)圖”

          2)百度:“GIF動(dòng)圖資源”

          或者干脆找個(gè)2D游戲素材網(wǎng)站也行,里面有很多角色人物素材在里面。

          二、python實(shí)現(xiàn)代碼

          2.1 目錄結(jié)構(gòu)

          項(xiàng)目的目錄結(jié)構(gòu)整體如下:main.py為主程序代碼。

          normal下的GIF圖是寵物平常會(huì)隨機(jī)切換的動(dòng)作GIF圖, click下面的GIF圖是點(diǎn)擊寵物之后的寵物動(dòng)作的GIF圖。

          dialog.txt 記錄了寵物的對(duì)話信息。

          tigerIcon.jpg是縮小到托盤后托盤圖標(biāo)的圖片。

          2.2 實(shí)現(xiàn)代碼

          2.2.1 引用包

          os包用于加載文件,sys包用于退出程序,random包用于程序中一些需要調(diào)用隨機(jī)數(shù)的操作。其他的三個(gè)包則是用于實(shí)現(xiàn)桌面寵物的基礎(chǔ)。


          import?os
          import?sys
          import?random
          from?PyQt5.QtGui?import?*
          from?PyQt5.QtCore?import?*
          from?PyQt5.QtWidgets?import?*

          2.2.2 主代碼部分


          if?__name__?==?'__main__':
          ????#?創(chuàng)建了一個(gè)QApplication對(duì)象,對(duì)象名為app,帶兩個(gè)參數(shù)argc,argv
          ????#?所有的PyQt5應(yīng)用必須創(chuàng)建一個(gè)應(yīng)用(Application)對(duì)象。sys.argv參數(shù)是一個(gè)來自命令行的參數(shù)列表。
          ????app?=?QApplication(sys.argv)
          ????#?窗口組件初始化
          ????pet?=?DesktopPet()
          ????# 1. 進(jìn)入時(shí)間循環(huán);
          ????# 2. wait,直到響應(yīng)app可能的輸入;
          ????# 3. QT接收和處理用戶及系統(tǒng)交代的事件(消息),并傳遞到各個(gè)窗口;
          ????# 4. 程序遇到exit()退出時(shí),機(jī)會(huì)返回exec()的值。
          ????sys.exit(app.exec_())

          2.2.3 代碼運(yùn)行流程

          整個(gè)運(yùn)行流程為:

          1. 通過self.init():實(shí)現(xiàn)窗體的初始化,寵物的GIF圖在這個(gè)窗體中播放

          2. 通過self.initPall():配置托盤化

          3. 通過self.initPetImage():將寵物的靜態(tài)GIF資源,包括對(duì)話和GIF動(dòng)圖進(jìn)行加載

          4. 通過self.petNormalAction():實(shí)現(xiàn)寵物隨機(jī)切換動(dòng)作和語句的功能


          class?DesktopPet(QWidget):
          ????def?__init__(self,?parent=None,?**kwargs):
          ????????super(DesktopPet,?self).__init__(parent)
          ????????#?窗體初始化
          ????????self.init()
          ????????#?托盤化初始
          ????????self.initPall()
          ????????#?寵物靜態(tài)gif圖加載
          ????????self.initPetImage()
          ????????#?寵物正常待機(jī),實(shí)現(xiàn)隨機(jī)切換動(dòng)作
          ????????self.petNormalAction()

          1、加載顯示GIF動(dòng)圖的窗體,通過函數(shù)init實(shí)現(xiàn),其代碼配置如下:

          這幾句的作用是對(duì)展示寵物的窗體進(jìn)行一些初步的設(shè)置,使得白色GIF圖能夠去掉背景的白色,將GIF圖透明的展示出來。

          #?窗體初始化
          def?init(self):
          ????#?初始化
          ????#?設(shè)置窗口屬性:窗口無標(biāo)題欄且固定在最前面
          ????#?FrameWindowHint:無邊框窗口
          ????#?WindowStaysOnTopHint:?窗口總顯示在最上面
          ????#?SubWindow:?新窗口部件是一個(gè)子窗口,而無論窗口部件是否有父窗口部件
          ????#?https://blog.csdn.net/kaida1234/article/details/79863146
          ????self.setWindowFlags(Qt.FramelessWindowHint?|?Qt.WindowStaysOnTopHint?|?Qt.SubWindow)
          ????#?setAutoFillBackground(True)表示的是自動(dòng)填充背景,False為透明背景
          ????self.setAutoFillBackground(False)
          ????#?窗口透明,窗體空間不透明
          ????self.setAttribute(Qt.WA_TranslucentBackground,?True)
          ????#?重繪組件、刷新
          ????self.repaint()

          2、實(shí)現(xiàn)能托盤顯示的功能,通過函數(shù)initPall實(shí)現(xiàn),其代碼配置如下:

          主要有下面這幾個(gè)操作:

          (1)讀取靜態(tài)圖片資源設(shè)置托盤化的圖標(biāo)。

          (2)設(shè)置托盤化圖片點(diǎn)擊右鍵顯示的菜單,并對(duì)這些菜單的點(diǎn)擊操作進(jìn)行設(shè)置。

          流程代碼如下:


          #?托盤化設(shè)置初始化
          def?initPall(self):
          ????#?導(dǎo)入準(zhǔn)備在托盤化顯示上使用的圖標(biāo)
          ????icons?=?os.path.join('tigerIcon.jpg')
          ????#?設(shè)置右鍵顯示最小化的菜單項(xiàng)
          ????#?菜單項(xiàng)退出,點(diǎn)擊后調(diào)用quit函數(shù)
          ????quit_action?=?QAction('退出',?self,?triggered=self.quit)
          ????#?設(shè)置這個(gè)點(diǎn)擊選項(xiàng)的圖片
          ????quit_action.setIcon(QIcon(icons))
          ????#?菜單項(xiàng)顯示,點(diǎn)擊后調(diào)用showing函數(shù)
          ????showing?=?QAction(u'顯示',?self,?triggered=self.showwin)
          ????#?新建一個(gè)菜單項(xiàng)控件
          ????self.tray_icon_menu?=?QMenu(self)
          ????#?在菜單欄添加一個(gè)無子菜單的菜單項(xiàng)‘退出’
          ????self.tray_icon_menu.addAction(quit_action)
          ????#?在菜單欄添加一個(gè)無子菜單的菜單項(xiàng)‘顯示’
          ????self.tray_icon_menu.addAction(showing)
          ????#?QSystemTrayIcon類為應(yīng)用程序在系統(tǒng)托盤中提供一個(gè)圖標(biāo)
          ????self.tray_icon?=?QSystemTrayIcon(self)
          ????#?設(shè)置托盤化圖標(biāo)
          ????self.tray_icon.setIcon(QIcon(icons))
          ????#?設(shè)置托盤化菜單項(xiàng)
          ????self.tray_icon.setContextMenu(self.tray_icon_menu)
          ????#?展示
          ????self.tray_icon.show()

          其中‘退出’項(xiàng)涉及到的函數(shù)代碼如下:

          #?退出操作,關(guān)閉程序
          def?quit(self):
          ????self.close()
          ????sys.exit()

          其中‘顯示’項(xiàng)涉及到的函數(shù)代碼如下:

          #?顯示寵物
          def?showwin(self):
          ????#?setWindowOpacity()設(shè)置窗體的透明度,通過調(diào)整窗體透明度實(shí)現(xiàn)寵物的展示和隱藏
          ????self.setWindowOpacity(1)

          3、寵物靜態(tài)資源的加載,通過函數(shù)initPetImage實(shí)現(xiàn),其代碼配置如下:

          靜態(tài)資源的加載主要涉及兩個(gè)部分,對(duì)話框內(nèi)容的加載和圖片內(nèi)容的加載。

          #?寵物靜態(tài)gif圖加載
          def?initPetImage(self):
          ????#?對(duì)話框定義
          ????self.talkLabel?=?QLabel(self)
          ????#?對(duì)話框樣式設(shè)計(jì)
          ????self.talkLabel.setStyleSheet("font:15pt?'楷體';border-width:?1px;color:blue;")?
          ????#?定義顯示圖片部分
          ????self.image?=?QLabel(self)
          ????#?QMovie是一個(gè)可以存放動(dòng)態(tài)視頻的類,一般是配合QLabel使用的,可以用來存放GIF動(dòng)態(tài)圖
          ????self.movie?=?QMovie("normal/normal1.gif")
          ????#?設(shè)置標(biāo)簽大小
          ????self.movie.setScaledSize(QSize(200,?200))
          ????#?將Qmovie在定義的image中顯示
          ????self.image.setMovie(self.movie)
          ????self.movie.start()
          ????self.resize(1024,?1024)
          ????#?調(diào)用自定義的randomPosition,會(huì)使得寵物出現(xiàn)位置隨機(jī)
          ????self.randomPosition()
          ????#?展示
          ????self.show()
          ????#?https://new.qq.com/rain/a/20211014a002rs00
          ????#?將寵物正常待機(jī)狀態(tài)的動(dòng)圖放入pet1中
          ????self.pet1?=?[]
          ????for?i?in?os.listdir("normal"):
          ????????self.pet1.append("normal/"?+?i)
          ????#?將寵物正常待機(jī)狀態(tài)的對(duì)話放入pet2中
          ????self.dialog?=?[]
          ????#?讀取目錄下dialog文件
          ????with?open("dialog.txt",?"r")?as?f:
          ????????text?=?f.read()
          ????????#?以\n?即換行符為分隔符,分割放進(jìn)dialog中
          ????????self.dialog?=?text.split("\n")

          其中我們希望寵物出現(xiàn)的位置是隨機(jī)的而不是固定的,那么便通過 randomPosition()實(shí)現(xiàn)寵物出現(xiàn)位置的隨機(jī)。

          #?寵物隨機(jī)位置
          def?randomPosition(self):
          ????#?screenGeometry()函數(shù)提供有關(guān)可用屏幕幾何的信息
          ????screen_geo?=?QDesktopWidget().screenGeometry()
          ????#?獲取窗口坐標(biāo)系
          ????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)

          4、寵物正常待機(jī),實(shí)現(xiàn)隨機(jī)切換動(dòng)作,對(duì)話框通過函數(shù)petNormalAction實(shí)現(xiàn),其代碼配置如下

          這里通過QTimer實(shí)現(xiàn)定時(shí)操作,到達(dá)設(shè)置的時(shí)間即調(diào)用相關(guān)的函數(shù)。其中condition為標(biāo)識(shí)寵物狀態(tài)的flag,0為平常狀態(tài),1為點(diǎn)擊狀態(tài),這個(gè)狀態(tài)可按照自己的喜好拓展。talk_condition同理,為標(biāo)識(shí)寵物對(duì)話狀態(tài)的flag。

          #?寵物正常待機(jī)動(dòng)作
          def?petNormalAction(self):
          ????#?每隔一段時(shí)間做個(gè)動(dòng)作
          ????#?定時(shí)器設(shè)置
          ????self.timer?=?QTimer()
          ????#?時(shí)間到了自動(dòng)執(zhí)行
          ????self.timer.timeout.connect(self.randomAct)
          ????#?動(dòng)作時(shí)間切換設(shè)置
          ????self.timer.start(3000)
          ????#?寵物狀態(tài)設(shè)置為正常
          ????self.condition?=?0
          ????#?每隔一段時(shí)間切換對(duì)話
          ????self.talkTimer?=?QTimer()
          ????self.talkTimer.timeout.connect(self.talk)
          ????self.talkTimer.start(3000)
          ????#?對(duì)話狀態(tài)設(shè)置為常態(tài)
          ????self.talk_condition?=?0
          ????#?寵物對(duì)話框
          ????self.talk()

          其中,通過randomAct實(shí)現(xiàn)寵物動(dòng)作的隨機(jī)切換,通過talk實(shí)現(xiàn)對(duì)話框內(nèi)容的切換,其代碼如下:

          self.pet1和self.dialog在初始化的時(shí)候即定義了。這里可以按照自己的喜好進(jìn)行拓展,用多個(gè)if-else if實(shí)現(xiàn)多種狀態(tài)的切換和定義,增加一些喂食,玩耍動(dòng)作等。

          #?隨機(jī)動(dòng)作切換
          def?randomAct(self):
          ????#?condition記錄寵物狀態(tài),寵物狀態(tài)為0時(shí),代表正常待機(jī)
          ????if?not?self.condition:
          ????????#?隨機(jī)選擇裝載在pet1里面的gif圖進(jìn)行展示,實(shí)現(xiàn)隨機(jī)切換
          ????????self.movie?=?QMovie(random.choice(self.pet1))
          ????????#?寵物大小
          ????????self.movie.setScaledSize(QSize(200,?200))
          ????????#?將動(dòng)畫添加到label中
          ????????self.image.setMovie(self.movie)
          ????????#?開始播放動(dòng)畫
          ????????self.movie.start()
          ????#?condition不為0,轉(zhuǎn)為切換特有的動(dòng)作,實(shí)現(xiàn)寵物的點(diǎn)擊反饋
          ????#?這里可以通過else-if語句往下拓展做更多的交互功能
          ????else:
          ????????#?讀取特殊狀態(tài)圖片路徑
          ????????self.movie?=?QMovie("./click/click.gif")
          ????????#?寵物大小
          ????????self.movie.setScaledSize(QSize(200,?200))
          ????????#?將動(dòng)畫添加到label中
          ????????self.image.setMovie(self.movie)
          ????????#?開始播放動(dòng)畫
          ????????self.movie.start()
          ????????#?寵物狀態(tài)設(shè)置為正常待機(jī)
          ????????self.condition?=?0
          ????????self.talk_condition?=?0

          #?寵物對(duì)話框行為處理
          def?talk(self):
          ????if?not?self.talk_condition:
          ????????#?talk_condition為0則選取加載在dialog中的語句
          ????????self.talkLabel.setText(random.choice(self.dialog))
          ????????#?設(shè)置樣式
          ????????self.talkLabel.setStyleSheet(
          ????????????"font:?bold;"
          ????????????"font:25pt?'楷體';"
          ????????????"color:white;"
          ????????????"background-color:?white"
          ????????????"url(:/)"
          ????????)
          ????????#?根據(jù)內(nèi)容自適應(yīng)大小
          ????????self.talkLabel.adjustSize()
          ????else:
          ????????#?talk_condition為1顯示為別點(diǎn)我,這里同樣可以通過if-else-if來拓展對(duì)應(yīng)的行為
          ????????self.talkLabel.setText("別點(diǎn)我")
          ????????self.talkLabel.setStyleSheet(
          ????????????"font:?bold;"
          ????????????"font:25pt?'楷體';"
          ????????????"color:white;"
          ????????????"background-color:?white"
          ????????????"url(:/)"
          ????????)
          ????????self.talkLabel.adjustSize()
          ????????#?設(shè)置為正常狀態(tài)
          ????????self.talk_condition?=?0

          5、實(shí)現(xiàn)能夠拖動(dòng)寵物,通過多個(gè)自帶函數(shù)實(shí)現(xiàn),其代碼配置如下:

          實(shí)現(xiàn)寵物的拖動(dòng)主要通過三個(gè)函數(shù)實(shí)現(xiàn),mouserPressEvent負(fù)責(zé)在鼠標(biāo)點(diǎn)擊判斷其是否在寵物窗口上,如果在則將寵物和鼠標(biāo)的位置綁定,并執(zhí)行點(diǎn)擊改變寵物GIF圖和對(duì)話框的操作。

          mouseMoveEvent實(shí)現(xiàn)按下后寵物跟著鼠標(biāo)移動(dòng)

          mouseReleaseEvent將之前的鎖定取消

          #?鼠標(biāo)左鍵按下時(shí),?寵物將和鼠標(biāo)位置綁定
          def?mousePressEvent(self,?event):
          ????#?更改寵物狀態(tài)為點(diǎn)擊
          ????self.condition?=?1
          ????#?更改寵物對(duì)話狀態(tài)
          ????self.talk_condition?=?1
          ????#?即可調(diào)用對(duì)話狀態(tài)改變
          ????self.talk()
          ????#?即刻加載寵物點(diǎn)擊動(dòng)畫
          ????self.randomAct()
          ????if?event.button()?==?Qt.LeftButton:
          ????????self.is_follow_mouse?=?True
          ????#?globalPos()?事件觸發(fā)點(diǎn)相對(duì)于桌面的位置
          ????#?pos()?程序相對(duì)于桌面左上角的位置,實(shí)際是窗口的左上角坐標(biāo)
          ????self.mouse_drag_pos?=?event.globalPos()?-?self.pos()
          ????event.accept()
          ????#?拖動(dòng)時(shí)鼠標(biāo)圖形的設(shè)置
          ????self.setCursor(QCursor(Qt.OpenHandCursor))

          #?鼠標(biāo)移動(dòng)時(shí)調(diào)用,實(shí)現(xiàn)寵物隨鼠標(biāo)移動(dòng)
          def?mouseMoveEvent(self,?event):
          ????#?如果鼠標(biāo)左鍵按下,且處于綁定狀態(tài)
          ????if?Qt.LeftButton?and?self.is_follow_mouse:
          ????????#?寵物隨鼠標(biāo)進(jìn)行移動(dòng)
          ????????self.move(event.globalPos()?-?self.mouse_drag_pos)
          ????event.accept()

          #?鼠標(biāo)釋放調(diào)用,取消綁定
          def?mouseReleaseEvent(self,?event):
          ????self.is_follow_mouse?=?False
          ????#?鼠標(biāo)圖形設(shè)置為箭頭
          ????self.setCursor(QCursor(Qt.ArrowCursor))

          6、實(shí)現(xiàn)寵物右鍵點(diǎn)擊具有交互功能,通過函數(shù)contextMenuEvent實(shí)現(xiàn),其代碼配置如下:

          退出操作通過 qApp.quit()實(shí)現(xiàn),直接退出相應(yīng)的QT程序。

          隱藏操作則通過self.setWindowOpacity(0)實(shí)現(xiàn),這個(gè)可控制窗口的透明度。

          #?寵物右鍵點(diǎn)擊交互
          def?contextMenuEvent(self,?event):
          ????#?定義菜單
          ????menu?=?QMenu(self)
          ????#?定義菜單項(xiàng)
          ????quitAction?=?menu.addAction("退出")
          ????hide?=?menu.addAction("隱藏")
          ????#?使用exec_()方法顯示菜單。從鼠標(biāo)右鍵事件對(duì)象中獲得當(dāng)前坐標(biāo)。mapToGlobal()方法把當(dāng)前組件的相對(duì)坐標(biāo)轉(zhuǎn)換為窗口(window)的絕對(duì)坐標(biāo)。
          ????action?=?menu.exec_(self.mapToGlobal(event.pos()))
          ????#?點(diǎn)擊事件為退出
          ????if?action?==?quitAction:
          ????????qApp.quit()
          ????#?點(diǎn)擊事件為隱藏
          ????if?action?==?hide:
          ????????#?通過設(shè)置透明度方式隱藏寵物
          ????????self.setWindowOpacity(0)

          7、鼠標(biāo)移到寵物上的時(shí)候顯示為閉合的手

          #?鼠標(biāo)移進(jìn)時(shí)調(diào)用
          def?enterEvent(self,?event):
          ????#?設(shè)置鼠標(biāo)形狀 Qt.ClosedHandCursor ??非指向手
          ????self.setCursor(Qt.ClosedHandCursor)

          2.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()
          ????????#?寵物靜態(tài)gif圖加載
          ????????self.initPetImage()
          ????????#?寵物正常待機(jī),實(shí)現(xiàn)隨機(jī)切換動(dòng)作
          ????????self.petNormalAction()
          ?
          ?
          ????#?窗體初始化
          ????def?init(self):
          ????????#?初始化
          ????????#?設(shè)置窗口屬性:窗口無標(biāo)題欄且固定在最前面
          ????????#?FrameWindowHint:無邊框窗口
          ????????#?WindowStaysOnTopHint:?窗口總顯示在最上面
          ????????#?SubWindow:?新窗口部件是一個(gè)子窗口,而無論窗口部件是否有父窗口部件
          ????????#?https://blog.csdn.net/kaida1234/article/details/79863146
          ????????self.setWindowFlags(Qt.FramelessWindowHint?|?Qt.WindowStaysOnTopHint?|?Qt.SubWindow)
          ????????#?setAutoFillBackground(True)表示的是自動(dòng)填充背景,False為透明背景
          ????????self.setAutoFillBackground(False)
          ????????#?窗口透明,窗體空間不透明
          ????????self.setAttribute(Qt.WA_TranslucentBackground,?True)
          ????????#?重繪組件、刷新
          ????????self.repaint()
          ?
          ????#?托盤化設(shè)置初始化
          ????def?initPall(self):
          ????????#?導(dǎo)入準(zhǔn)備在托盤化顯示上使用的圖標(biāo)
          ????????icons?=?os.path.join('tigerIcon.jpg')
          ????????#?設(shè)置右鍵顯示最小化的菜單項(xiàng)
          ????????#?菜單項(xiàng)退出,點(diǎn)擊后調(diào)用quit函數(shù)
          ????????quit_action?=?QAction('退出',?self,?triggered=self.quit)
          ????????#?設(shè)置這個(gè)點(diǎn)擊選項(xiàng)的圖片
          ????????quit_action.setIcon(QIcon(icons))
          ????????#?菜單項(xiàng)顯示,點(diǎn)擊后調(diào)用showing函數(shù)
          ????????showing?=?QAction(u'顯示',?self,?triggered=self.showwin)
          ????????#?新建一個(gè)菜單項(xiàng)控件
          ????????self.tray_icon_menu?=?QMenu(self)
          ????????#?在菜單欄添加一個(gè)無子菜單的菜單項(xiàng)‘退出’
          ????????self.tray_icon_menu.addAction(quit_action)
          ????????#?在菜單欄添加一個(gè)無子菜單的菜單項(xiàng)‘顯示’
          ????????self.tray_icon_menu.addAction(showing)
          ????????#?QSystemTrayIcon類為應(yīng)用程序在系統(tǒng)托盤中提供一個(gè)圖標(biāo)
          ????????self.tray_icon?=?QSystemTrayIcon(self)
          ????????#?設(shè)置托盤化圖標(biāo)
          ????????self.tray_icon.setIcon(QIcon(icons))
          ????????#?設(shè)置托盤化菜單項(xiàng)
          ????????self.tray_icon.setContextMenu(self.tray_icon_menu)
          ????????#?展示
          ????????self.tray_icon.show()
          ?
          ????#?寵物靜態(tài)gif圖加載
          ????def?initPetImage(self):
          ????????#?對(duì)話框定義
          ????????self.talkLabel?=?QLabel(self)
          ????????#?對(duì)話框樣式設(shè)計(jì)
          ????????self.talkLabel.setStyleSheet("font:15pt?'楷體';border-width:?1px;color:blue;")
          ????????#?定義顯示圖片部分
          ????????self.image?=?QLabel(self)
          ????????#?QMovie是一個(gè)可以存放動(dòng)態(tài)視頻的類,一般是配合QLabel使用的,可以用來存放GIF動(dòng)態(tài)圖
          ????????self.movie?=?QMovie("normal/normal1.gif")
          ????????#?設(shè)置標(biāo)簽大小
          ????????self.movie.setScaledSize(QSize(200,?200))
          ????????#?將Qmovie在定義的image中顯示
          ????????self.image.setMovie(self.movie)
          ????????self.movie.start()
          ????????self.resize(1024,?1024)
          ????????#?調(diào)用自定義的randomPosition,會(huì)使得寵物出現(xiàn)位置隨機(jī)
          ????????self.randomPosition()
          ????????#?展示
          ????????self.show()
          ????????#?https://new.qq.com/rain/a/20211014a002rs00
          ????????#?將寵物正常待機(jī)狀態(tài)的動(dòng)圖放入pet1中
          ????????self.pet1?=?[]
          ????????for?i?in?os.listdir("normal"):
          ????????????self.pet1.append("normal/"?+?i)
          ????????#?將寵物正常待機(jī)狀態(tài)的對(duì)話放入pet2中
          ????????self.dialog?=?[]
          ????????#?讀取目錄下dialog文件
          ????????with?open("dialog.txt",?"r")?as?f:
          ????????????text?=?f.read()
          ????????????#?以\n?即換行符為分隔符,分割放進(jìn)dialog中
          ????????????self.dialog?=?text.split("\n")
          ?
          ????#?寵物正常待機(jī)動(dòng)作
          ????def?petNormalAction(self):
          ????????#?每隔一段時(shí)間做個(gè)動(dòng)作
          ????????#?定時(shí)器設(shè)置
          ????????self.timer?=?QTimer()
          ????????#?時(shí)間到了自動(dòng)執(zhí)行
          ????????self.timer.timeout.connect(self.randomAct)
          ????????#?動(dòng)作時(shí)間切換設(shè)置
          ????????self.timer.start(3000)
          ????????#?寵物狀態(tài)設(shè)置為正常
          ????????self.condition?=?0
          ????????#?每隔一段時(shí)間切換對(duì)話
          ????????self.talkTimer?=?QTimer()
          ????????self.talkTimer.timeout.connect(self.talk)
          ????????self.talkTimer.start(3000)
          ????????#?對(duì)話狀態(tài)設(shè)置為常態(tài)
          ????????self.talk_condition?=?0
          ????????#?寵物對(duì)話框
          ????????self.talk()
          ?
          ????#?隨機(jī)動(dòng)作切換
          ????def?randomAct(self):
          ????????#?condition記錄寵物狀態(tài),寵物狀態(tài)為0時(shí),代表正常待機(jī)
          ????????if?not?self.condition:
          ????????????#?隨機(jī)選擇裝載在pet1里面的gif圖進(jìn)行展示,實(shí)現(xiàn)隨機(jī)切換
          ????????????self.movie?=?QMovie(random.choice(self.pet1))
          ????????????#?寵物大小
          ????????????self.movie.setScaledSize(QSize(200,?200))
          ????????????#?將動(dòng)畫添加到label中
          ????????????self.image.setMovie(self.movie)
          ????????????#?開始播放動(dòng)畫
          ????????????self.movie.start()
          ????????#?condition不為0,轉(zhuǎn)為切換特有的動(dòng)作,實(shí)現(xiàn)寵物的點(diǎn)擊反饋
          ????????#?這里可以通過else-if語句往下拓展做更多的交互功能
          ????????else:
          ????????????#?讀取特殊狀態(tài)圖片路徑
          ????????????self.movie?=?QMovie("./click/click.gif")
          ????????????#?寵物大小
          ????????????self.movie.setScaledSize(QSize(200,?200))
          ????????????#?將動(dòng)畫添加到label中
          ????????????self.image.setMovie(self.movie)
          ????????????#?開始播放動(dòng)畫
          ????????????self.movie.start()
          ????????????#?寵物狀態(tài)設(shè)置為正常待機(jī)
          ????????????self.condition?=?0
          ????????????self.talk_condition?=?0
          ?
          ????#?寵物對(duì)話框行為處理
          ????def?talk(self):
          ????????if?not?self.talk_condition:
          ????????????#?talk_condition為0則選取加載在dialog中的語句
          ????????????self.talkLabel.setText(random.choice(self.dialog))
          ????????????#?設(shè)置樣式
          ????????????self.talkLabel.setStyleSheet(
          ????????????????"font:?bold;"
          ????????????????"font:25pt?'楷體';"
          ????????????????"color:white;"
          ????????????????"background-color:?white"
          ????????????????"url(:/)"
          ????????????)
          ????????????#?根據(jù)內(nèi)容自適應(yīng)大小
          ????????????self.talkLabel.adjustSize()
          ????????else:
          ????????????#?talk_condition為1顯示為別點(diǎn)我,這里同樣可以通過if-else-if來拓展對(duì)應(yīng)的行為
          ????????????self.talkLabel.setText("別點(diǎn)我")
          ????????????self.talkLabel.setStyleSheet(
          ????????????????"font:?bold;"
          ????????????????"font:25pt?'楷體';"
          ????????????????"color:white;"
          ????????????????"background-color:?white"
          ????????????????"url(:/)"
          ????????????)
          ????????????self.talkLabel.adjustSize()
          ????????????#?設(shè)置為正常狀態(tài)
          ????????????self.talk_condition?=?0
          ?
          ????#?退出操作,關(guān)閉程序
          ????def?quit(self):
          ????????self.close()
          ????????sys.exit()
          ?
          ????#?顯示寵物
          ????def?showwin(self):
          ????????#?setWindowOpacity()設(shè)置窗體的透明度,通過調(diào)整窗體透明度實(shí)現(xiàn)寵物的展示和隱藏
          ????????self.setWindowOpacity(1)
          ?
          ????#?寵物隨機(jī)位置
          ????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)
          ?
          ????#?鼠標(biāo)左鍵按下時(shí),?寵物將和鼠標(biāo)位置綁定
          ????def?mousePressEvent(self,?event):
          ????????#?更改寵物狀態(tài)為點(diǎn)擊
          ????????self.condition?=?1
          ????????#?更改寵物對(duì)話狀態(tài)
          ????????self.talk_condition?=?1
          ????????#?即可調(diào)用對(duì)話狀態(tài)改變
          ????????self.talk()
          ????????#?即刻加載寵物點(diǎn)擊動(dòng)畫
          ????????self.randomAct()
          ????????if?event.button()?==?Qt.LeftButton:
          ????????????self.is_follow_mouse?=?True
          ????????#?globalPos()?事件觸發(fā)點(diǎn)相對(duì)于桌面的位置
          ????????#?pos()?程序相對(duì)于桌面左上角的位置,實(shí)際是窗口的左上角坐標(biāo)
          ????????self.mouse_drag_pos?=?event.globalPos()?-?self.pos()
          ????????event.accept()
          ????????#?拖動(dòng)時(shí)鼠標(biāo)圖形的設(shè)置
          ????????self.setCursor(QCursor(Qt.OpenHandCursor))
          ?
          ????#?鼠標(biāo)移動(dòng)時(shí)調(diào)用,實(shí)現(xiàn)寵物隨鼠標(biāo)移動(dòng)
          ????def?mouseMoveEvent(self,?event):
          ????????#?如果鼠標(biāo)左鍵按下,且處于綁定狀態(tài)
          ????????if?Qt.LeftButton?and?self.is_follow_mouse:
          ????????????#?寵物隨鼠標(biāo)進(jìn)行移動(dòng)
          ????????????self.move(event.globalPos()?-?self.mouse_drag_pos)
          ????????event.accept()
          ?
          ????#?鼠標(biāo)釋放調(diào)用,取消綁定
          ????def?mouseReleaseEvent(self,?event):
          ????????self.is_follow_mouse?=?False
          ????????#?鼠標(biāo)圖形設(shè)置為箭頭
          ????????self.setCursor(QCursor(Qt.ArrowCursor))
          ?
          ?
          ????#?鼠標(biāo)移進(jìn)時(shí)調(diào)用
          ????def?enterEvent(self,?event):
          ????????#?設(shè)置鼠標(biāo)形狀?Qt.ClosedHandCursor???非指向手
          ????????self.setCursor(Qt.ClosedHandCursor)
          ?
          ????#?寵物右鍵點(diǎn)擊交互
          ????def?contextMenuEvent(self,?event):
          ????????#?定義菜單
          ????????menu?=?QMenu(self)
          ????????#?定義菜單項(xiàng)
          ????????quitAction?=?menu.addAction("退出")
          ????????hide?=?menu.addAction("隱藏")
          ????????#?使用exec_()方法顯示菜單。從鼠標(biāo)右鍵事件對(duì)象中獲得當(dāng)前坐標(biāo)。mapToGlobal()方法把當(dāng)前組件的相對(duì)坐標(biāo)轉(zhuǎn)換為窗口(window)的絕對(duì)坐標(biāo)。
          ????????action?=?menu.exec_(self.mapToGlobal(event.pos()))
          ????????#?點(diǎn)擊事件為退出
          ????????if?action?==?quitAction:
          ????????????qApp.quit()
          ????????#?點(diǎn)擊事件為隱藏
          ????????if?action?==?hide:
          ????????????#?通過設(shè)置透明度方式隱藏寵物
          ????????????self.setWindowOpacity(0)
          ?
          ?
          if?__name__?==?'__main__':
          ????#?創(chuàng)建了一個(gè)QApplication對(duì)象,對(duì)象名為app,帶兩個(gè)參數(shù)argc,argv
          ????#?所有的PyQt5應(yīng)用必須創(chuàng)建一個(gè)應(yīng)用(Application)對(duì)象。sys.argv參數(shù)是一個(gè)來自命令行的參數(shù)列表。
          ????app?=?QApplication(sys.argv)
          ????#?窗口組件初始化
          ????pet?=?DesktopPet()
          ????# 1. 進(jìn)入時(shí)間循環(huán);
          ????# 2. wait,直到響應(yīng)app可能的輸入;
          ????# 3. QT接收和處理用戶及系統(tǒng)交代的事件(消息),并傳遞到各個(gè)窗口;
          ????# 4. 程序遇到exit()退出時(shí),機(jī)會(huì)返回exec()的值。
          ????sys.exit(app.exec_())

          三、程序打包

          3.1 安裝pyinstaller

          pip?install?pyinstaller?

          如果提示黃色提示pip版本問題,照著上面的提示修改即可。

          3.2 項(xiàng)目目錄下完成打包

          進(jìn)入打開cmd命令行,進(jìn)入項(xiàng)目目錄,輸入命令

          pyinstaller?-F?-w?main.py

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

          將main.exe放到主目錄下就可正常運(yùn)行。

          四、總結(jié)與參考資料

          4.1 項(xiàng)目百度網(wǎng)盤:

          已經(jīng)將代碼和exe文件,打包。

          DeskTopPetEXE為帶打包好的文件。

          DeskTopPet是打包前的文件。

          公眾號(hào)后臺(tái)回復(fù):桌面寵物,即可下載。

          寫之前挺開心的,寫的時(shí)候也挺開心的,寫完之后就有點(diǎn)索然無味了。

          純粹是因?yàn)闊o聊寫著玩的,下次再試試能不能弄個(gè)3D的。

          ·················END·················

          推薦閱讀

          ?? ?我與身旁的美女,格格不入,我決定...?? ?請(qǐng)做好3年內(nèi)隨時(shí)失業(yè)的準(zhǔn)備?????該死,這糟糕的心動(dòng)感

          瀏覽 37
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青娱乐青青草视频 | 操逼网站免费 | 欲色视频| 成人A片一级 | 大鸡巴操小逼视频 |