桌面太單調?今天就帶大家,一起用Python的PyQt5開發一個有趣的自定義桌面動畫掛件,看看實現的動畫掛件效果!

下面,我們開始介紹這個自定義桌面動畫掛件的制作過程。
一、核心功能設計
實現將動態圖gif或視頻轉成一個桌面動畫掛件,知識點主要涉及了對GIF圖/視頻解析,人像提取分割,PyQt5窗體設置,自定義掛件動畫實現,ico圖標生成,程序打包等。
拆解需求,大致可以整理出我們需要分為以下幾步完成:
1.對gif或者視頻進行逐幀解析,獲取轉換的圖片,提取圖像中人體區域,並對圖片進行批量尺寸大小修改替換
2.初始化設置動畫掛件窗體顯示效果,窗體位置、大小等
3.桌面動畫掛件功能實現,動畫輪播、鼠標控制掛件位置拖動
4.掛件打包圖標設置、打包配置
二、實現步驟
干貨主要有:
① 200 多本 Python 電子書(和經典的書籍)應該有
② Python標准庫資料(最全中文版)
③ 項目源碼(四五十個有趣且可靠的練手項目及源碼)
④ Python基礎入門、爬蟲、網絡開發、大數據分析方面的視頻(適合小白學習)
⑤ Python學習路線圖(告別不入流的學習)
Python學習交流Q群101677771
- 解析提取,修改圖片
GIF圖解析:
首先我們需要將Gif逐幀進行解析 ,轉換成圖片格式。代碼如下:
from PIL import Image # 導入PIL的Image包 import os gifFileName = "./demo.gif" # 把gif圖賦值給gifFileName im = Image.open(gifFileName) # 使用Image的open函數打開test.gif圖像 pngDir = gifFileName[:-4] # 倒着從gifFileName中的倒數第四個開始取字符(跳過.gif),賦值給pngDir,作為文件夾的名字 if not os.path.exists(pngDir): os.makedirs('./img') # 用圖片名創建一個文件夾,用來存放每幀圖片,名字為pngDir的值 try: while True: # 死循環 current = im.tell() # 用tell函數保存當前幀圖片,賦值給current im.save(pngDir+'/'+str(current+1)+'.png') # 調用save函數保存該幀圖片 im.seek(current+1) # 調用seek函數獲取下一幀圖片,參數變為current幀圖片+1 # 這里再次進入循環,當為最后一幀圖片時,seek會拋出異常,代碼執行except except EOFError: pass # 最后一幀時,seek拋出異常,進入這里,pass跳過
gif逐幀轉為圖片,效果如下:

視頻解析:
對視頻解析,也是逐幀進行解析,轉換成若干張圖片,代碼如下:
# 將視頻按照每一幀轉成圖片png import cv2 videoFileName = "./demo.mp4" # 把視頻路徑賦值給videoFileName pngDir = videoFileName[:-4] # 倒着從gifFileName中的倒數第四個開始取字符(跳過.后綴),賦值給pngDir,作為文件夾的名字 if not os.path.exists(pngDir): os.makedirs(pngDir) # 用圖片名創建一個文件夾,用來存放每幀圖片,名字為pngDir的值 # 視頻處理 分割成一幀幀圖片 cap = cv2.VideoCapture(videoFileName) num = 1 while True: # 逐幀讀取視頻 按順序保存到本地文件夾 ret, frame = cap.read() if ret: cv2.imwrite(f"{pngDir}/{num}.png", frame) # 保存一幀幀的圖片 num += 1 else: break cap.release() # 釋放資源
桌面小部件功能
初始化動畫部件
# 窗體初始化 def windowinit(self): self.x = 1650 self.y = 860 self.setGeometry(self.x, self.y, 300, 300) self.setWindowTitle('My Gadgets') self.img_num = 1 self.img_path = './image/{file}/{img}.png'.format(file=self.dis_file, img=str(self.img_num)) self.lab = QLabel(self) self.qpixmap = QPixmap(self.img_path) self.lab.setPixmap(self.qpixmap) self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow) self.setAutoFillBackground(False) self.setAttribute(Qt.WA_TranslucentBackground, True) self.show() def __init__(self): super(Gadgets, self).__init__() self.dis_file = "img1" self.windowinit() self.icon_quit() self.pos_first = self.pos() self.img_count = len(os.listdir('./image/{}'.format(self.dis_file)))
這樣只是完成了圖片的靜態顯示,下面我們來完成圖片的動態輪播效果
動畫輪播:
self.timer = QTimer() self.timer.timeout.connect(self.img_update) self.timer.start(100) def img_update(self): if self.img_num < self.img_count: self.img_num += 1 else: self.img_num = 1 self.img_path = './image/{file}/{img}.png'.format(file=self.dis_file, img=str(self.img_num)) self.qpixmap = QPixmap(self.img_path) self.lab.setPixmap(self.qpixmap)
鼠標控制掛件位置拖動:
def mousePressEvent(self, QMouseEvent): if QMouseEvent.button() == Qt.LeftButton: self.pos_first = QMouseEvent.globalPos() - self.pos() QMouseEvent.accept() self.setCursor(QCursor(Qt.OpenHandCursor)) def mouseMoveEvent(self, QMouseEvent): if Qt.LeftButton: self.move(QMouseEvent.globalPos() - self.pos_first) print(self.pos()) self.x, self.y = self.pos().x, self.pos().y QMouseEvent.accept() def quit(self): self.close() sys.exit()
到此為止,桌面小部件已開發完成,效果如下:

可以使用將程序打包為exe可執行文件直接發給你的朋友,這樣就不用安裝python環境了。