前言

前段时间,用PyQt5写了几篇文章,关于Python自制一款炫酷音乐播放器、自定义桌面动画挂件、车牌自动识别系统。今天就继续给大家分享一个实战案例,带大家一起用Python的PyQt5开发一个自定义动态桌面壁纸,好玩又有趣!

首先一起来看看最终实现的自定义动态壁纸效果:

下面,我们开始介绍这个自定义动态桌面的制作过程。

直接跳到文末获取粉丝专属福利。

一、核心功能设计

总体来说,我们需要实现将自己喜欢的视频转成一个动态桌面,知识点主要包含了对视频提取解析,视频轮播,PyQt5窗体设置,桌面句柄获取,自定义动态桌面壁纸实现等。

拆解需求,大致可以整理出我们需要分为以下几步完成:

  1. UI排版布局设计,确认动态壁纸功能设计
  2. 加载视频,对视频进行预览读取,保存视频路径等
  3. 动态壁纸功能实现应用,获取桌面句柄,轮播加载视频
  4. 关闭动态壁纸,在线壁纸资源获取等

二、实现步骤

之前有粉丝反馈说,想自己跟着文章自己敲敲代码,但是不知道具体需要哪些模块、包文件,后面我就把所有用到模块先放出来。

import os
import sys
from subprocess import call
from threading import Thread
from time import sleepimport cv2
from PyQt5 import QtCore,  QtWidgets
from PyQt5.QtCore import Qt,  QTimer
from PyQt5.QtGui import QImage, QPixmap, QIconfrom PyQt5.QtWidgets import QGridLayout, QPushButton, QMainWindow, QFileDialog, QLabel, QSystemTrayIcon, \QAction, QMenu, QMessageBox
from os import path as pathq

1. UI排版布局设计

根据动态壁纸所需要的功能,首先进行UI布局设计,我们这次还是使用的pyqt5。主要包含了加载读取本地视频、视频加载预览、动态壁纸应用、动态壁纸关闭等。核心设计代码如下:

# author:CSDN-Dragon少年
def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(505, 615)MainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.pushButton = QtWidgets.QPushButton(self.centralwidget)self.pushButton.setGeometry(QtCore.QRect(22, 10, 89, 31))self.pushButton.setObjectName("pushButton")self.pushButton.clicked.connect(self.openmp4)self.pushButton.setStyleSheet('''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''')self.groupBox = QtWidgets.QGroupBox(self.centralwidget)self.groupBox.setGeometry(QtCore.QRect(22, 50, 452, 351))self.groupBox.setObjectName("groupBox")self.widget = QtWidgets.QWidget(self.groupBox)self.widget.setGeometry(QtCore.QRect(11, 20, 430, 291))self.widget.setObjectName("widget")self.gridLayout_3 = QtWidgets.QGridLayout(self.widget)self.gridLayout_3.setObjectName("gridLayout_3")self.label = QLabel(self)self.label.resize(400, 300)self.label.setText("Waiting for video...")self.gridLayout_3.addWidget(self.label)self.close_widget = QtWidgets.QWidget(self.centralwidget)self.close_widget.setGeometry(QtCore.QRect(420, 0, 93, 41))self.close_widget.setObjectName("close_widget")self.close_layout = QGridLayout()  # 创建左侧部件的网格布局层self.close_widget.setLayout(self.close_layout)  # 设置左侧部件布局为网格self.left_close = QPushButton("")  # 关闭按钮self.left_close.clicked.connect(self.close)self.left_visit = QPushButton("")  # 空白按钮#self.left_visit.clicked.connect(MainWindow.big)self.left_mini = QPushButton("")  # 最小化按钮self.left_mini.clicked.connect(MainWindow.mini)self.close_layout.addWidget(self.left_mini, 0, 0, 1, 1)self.close_layout.addWidget(self.left_close, 0, 2, 1, 1)self.close_layout.addWidget(self.left_visit, 0, 1, 1, 1)self.left_close.setFixedSize(15, 15)  # 设置关闭按钮的大小self.left_visit.setFixedSize(15, 15)  # 设置按钮大小self.left_mini.setFixedSize(15, 15)  # 设置最小化按钮大小self.left_close.setStyleSheet('''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}''')self.left_visit.setStyleSheet('''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''')self.left_mini.setStyleSheet('''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''')self.horizontalLayout = QtWidgets.QHBoxLayout(self.close_widget)self.horizontalLayout.setContentsMargins(0, 0, 0, 0)self.horizontalLayout.setObjectName("horizontalLayout")self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_2.setGeometry(QtCore.QRect(77, 440, 133, 41))self.pushButton_2.setObjectName("pushButton_2")self.pushButton_2.clicked.connect(self.play)self.pushButton_2.setStyleSheet('''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''')self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_3.setGeometry(QtCore.QRect(308, 440, 111, 41))self.pushButton_3.setObjectName("pushButton_3")self.pushButton_3.clicked.connect(self.close_wall)self.pushButton_3.setStyleSheet('''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}''')self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_4.setGeometry(QtCore.QRect(187, 540, 133, 21))self.pushButton_4.setObjectName("pushButton_4")self.pushButton_4.clicked.connect(self.openurl)self.pushButton_4.setStyleSheet('''QPushButton{background:#222225;color:white;border-radius:5px;}QPushButton:hover{background:#222225;color:skyblue}''')MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 505, 23))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)self.groupBox.setStyleSheet('''color:white''')MainWindow.setWindowOpacity(0.95)  # 设置窗口透明度MainWindow.setAttribute(Qt.WA_TranslucentBackground)MainWindow.setWindowFlag(Qt.FramelessWindowHint)  # 隐藏边框
# author:Dragon少年
def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.pushButton.setText(_translate("MainWindow", "从本地选择"))self.groupBox.setTitle(_translate("MainWindow", "预览"))self.pushButton_2.setText(_translate("MainWindow", "应用"))self.pushButton_3.setText(_translate("MainWindow", "关闭壁纸"))self.pushButton_4.setText(_translate("MainWindow", "在线资源"))

UI实现效果如下:

UI布局设计完成,下面我们开始进行视频读取加载、预览功能实现。

2. 视频加载预览

接来下我们可以根据自己喜欢的视频,从本地读取视频,并且将视频预览播放显示。这里视频演示,博主还是用之前的那篇紫颜小姐姐的跳舞视频进行演示。

读取视频:

读取视频我们可以通过打开文件对话框,选择视频资源,开启一个子线程用来进行视频开启停止播放。核心代码如下:

# author: CSDN-Dragon少年
def openmp4(self):try:global pathpath, filetype = QFileDialog.getOpenFileName(None, "选择文件", '.',"视频文件(*.AVI;*.mov;*.rmvb;*.rm;*.FLV;*.mp4;*.3GP)")  # ;;All Files (*)if path == "":  # 未选择文件returnself.slotStart()t = Thread(target=self.Stop)t.start()  # 启动线程,即让线程开始执行except Exception as e:print (e)

视频流读取播放:

接下来,我们需要对视频文件进行按帧读取加载显示,并通过计时器实现动画效果。核心代码如下:

# author:CSDN-Dragon少年
def slotStart(self):videoName = pathif videoName != "":  # “”为用户取消self.cap = cv2.VideoCapture(videoName)self.timer_camera.start(50)self.timer_camera.timeout.connect(self.openFrame)
# author:CSDN-Dragon少年
def openFrame(self):if (self.cap.isOpened()):ret, self.frame = self.cap.read()if ret:frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)if self.detectFlag == True:# 检测代码self.frameself.label_num.setText("There are " + str(5) + " people.")height, width, bytesPerComponent = frame.shapebytesPerLine = bytesPerComponent * widthq_image = QImage(frame.data, width, height, bytesPerLine,QImage.Format_RGB888).scaled(self.label.width(), self.label.height())self.label.setPixmap(QPixmap.fromImage(q_image))else:self.cap.release()self.timer_camera.stop()  # 停止计时器

至此,我们已经可以实现视频读取加载,并且进行视频预览了,效果如下:

3. 动态壁纸功能实现

实现桌面壁纸替换,我们首先需要获取桌面句柄找到桌面窗体,覆写桌面窗体、调用加载的视频流,播放动态壁纸。

获取桌面句柄:

# author:CSDN-Dragon少年
def pretreatmentHandle():hwnd = win32gui.FindWindow("Progman", "Program Manager")win32gui.SendMessageTimeout(hwnd, 0x052C, 0, None, 0, 0x03E8)hwnd_WorkW = Nonewhile 1:hwnd_WorkW = win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)if not hwnd_WorkW:continuehView = win32gui.FindWindowEx(hwnd_WorkW, None, "SHELLDLL_DefView", None)# print('hwmd_hView: ', hView)if not hView:continueh = win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)while h:win32gui.SendMessage(h, 0x0010, 0, 0)  # WM_CLOSEh = win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)breakreturn hwnd

桌面覆写:

我们可以创建一个类,对窗体进行继承,进行视频流加载读取播放。核心代码如下:

# author: CSDN-Dragon少年
class MyMainWindow(QMainWindow, Ui_MainWindow):def __init__(self, parent=None):super(MyMainWindow, self).__init__(parent)self.ui = Ui_MainWindow()self.ui.setupUi(self)self.player = QMediaPlayer()self.player.setNotifyInterval(10000)self.player.setVideoOutput(self.ui.videowidget)self.player.setMuted(bool(1 - self.player.isMuted()))self.setWindowFlags(Qt.FramelessWindowHint)self.setupUi(self)self.go()# author: CSDN-Dragon少年def go(self):self.ui.videowidget.setFullScreen(True)with open("./filename.txt", 'r', encoding='utf-8') as f:file_name = f.read()if file_name =='':file_name = 'lkf.mp4'print (file_name)if not os.path.exists(file_name):sys.exit()media = QMediaContent(QUrl(file_name))self.player.setMedia(media)self.mplayList = QMediaPlaylist()self.mplayList.addMedia(QMediaContent(QUrl.fromLocalFile(file_name)))self.player.setPlaylist(self.mplayList)self.mplayList.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop)win_hwnd = int(self.winId())video_h = int(self.ui.videowidget.winId())win32gui.SetParent(win_hwnd, h)win32gui.SetParent(video_h, h)win32gui.SetParent(video_h, win_hwnd)self.player.play()

这里我们把上面的py文件直接打包成exe文件,接下来我们在“应用”控件上进行事件绑定,直接调用exe执行,实现动态壁纸播放应用功能。核心代码如下:

# author: CSDN-Dragon少年
def play(self):if path == '':reply = QtWidgets.QMessageBox.question(self, '提示',"未加载选择视频",QtWidgets.QMessageBox.Yes)returnwith open("./filename.txt", 'w', encoding='utf-8') as f:f.truncate(0)print(f.write(str(path)))try:try:call('taskkill /F /IM play.exe')except:passos.system('start play.exe')except:passtry:if self.cap != []:self.cap.release()self.timer_camera.stop()  # 停止计时器else:Warming = QMessageBox.warning(self, "Warming", "Push the left upper corner button to Quit.",QMessageBox.Yes)except:pass

这样,我们就完成了动态壁纸加载应用功能了,效果如下:

4. 关闭动态壁纸

最后我们再实现下当前动态壁纸播放关闭功能,我们需要对当前桌面视频播放进行释放取消。代码如下:

# author:CSDN-Dragon少年def close_wall(self):try:call('taskkill /F /IM play.exe')except:pass

效果如下:

至此,整个自定义动态桌面壁纸功能就全部完成了,下面我们一起运行下看看动态壁纸效果。

源码及数据已上传,关注文末公众号回复【源码】即可获取完整源码

Python往期精彩:

  • 见过仙女蹦迪吗?一起用python做个小仙女代码蹦迪视频

  • python自制一款炫酷音乐播放器,想听啥随便搜!

  • 斗地主老是输?一起用Python做个AI出牌器,豆子蹭蹭涨!

  • 桌面太单调?一起用Python做个自定义动画挂件,好玩又有趣!

  • 一起用Python做个车牌自动识别系统,好玩又实用!

  • 桌面太单调?一起用Python做个自定义动态壁纸,竟然还可以放视频!

  • 一起用Python做个自动化弹钢琴脚本,我竟然弹出了《天空之城》!
    往期精彩源码均可通过下方公众号获取

桌面太单调?一起用Python做个自定义动态壁纸,竟然还可以放视频!相关推荐

  1. 桌面太单调?一起用Python做个自定义动画挂件,好玩又有趣!

    前言 前段时间,写了篇博客关于Python自制一款炫酷音乐播放器.有粉丝问我,音乐播放器为什么要用PyQt5,效果是不是比Tkinter赞?PyQt5真的可以实现这些炫酷的UI画面吗?之前没接触过Py ...

  2. 一起用Python做个上课点名器,好玩又实用!

    前言 前段时间,用PyQt5写了几篇文章,关于Python自制一款炫酷音乐播放器.自定义动态壁纸.车牌自动识别系统.今天就继续给大家分享一个读者粉丝投稿的,关于上课点名的实战案例,一起来看看是如何实现 ...

  3. 一起用Python做个自动化短视频生成脚本,实现热门视频流水线生产!

    前言 前几天有粉丝和我说,最近在网上看到一些视频营销号一天能发布几百条短视频, 感觉都是批量生成的,能不能用Python做个自动化短视频生成脚本呢? 今天就带大家一起用Python做个自动化视频生成脚 ...

  4. 一起用python做个炫酷音乐播放器【V3.0含源码及打包exe】

    前言 熟悉的小伙伴都知道,前段时间写了一篇关于音乐播放器的文章–Python自制一款炫酷音乐播放器.不少小伙伴私信我,对播放器提了一些改进建议,对播放器的一些逻辑bug优化完善.今天音乐播放器3.0版 ...

  5. 小年到了,回家抢票太难,用Python做个脚本12306自动查票以及自动购票....

    今天就是小年了,听说还有人买不到票?不要慌,今天咱们来用Python做一个自动查票抢票的脚本,24小时抢票,谁抢的过你!源码包已打包文件夹获取方式:点击这里[ Python全套资料] 即可获取. 准备 ...

  6. 用 Python 做了一个小姐姐跳舞的词云视频

    关注公众号:[小张Python],为你准备了 50+ 本Python 精品电子书籍 与 50G + 优质视频学习资料,后台回复关键字:1024 即可获取:如果对博文内容有什么疑问,公号后台添加作者[个 ...

  7. Python 实现macOS Catalina 动态壁纸定时设置

    前言 很不幸,我的电脑只能装 macOS High Sierra ,但是看他们的 Catalina 和 Mojave 的壁纸好炫酷,据说还可以根据日出时间切换壁纸和暗黑模式?!尽管条件限制,我还是想体 ...

  8. live2d动态壁纸android,live2dviewerex宅男自定义动态壁纸下载-live2dviewerex动态桌面2.0.4 官方安卓版下载_东坡手机下载...

    live2dviewerex动态桌面是一款非常有趣的手机动态壁纸,只需要QQ便能登录,在登录界面可以看到相关信息.首次进入APP有针对APP的详细帮助说明,请首次使用的用户认真阅读,上面会解决你的大多 ...

  9. 七夕节特辑,浏览器桌面太无聊,为什么不做个挂件来陪自己呢?

    相信很多人都玩过QQ宠物吧,QQ宠物停运之后,说实话心里还是有点不舍的,所以一直有着自己制作一只桌面宠物的想法,现在先在浏览器中试着实现了一下,感觉还是挺有趣的,如果有人喜欢,后续还可以加入更多的操作 ...

  10. 斗地主老是输?一起用Python做个AI出牌器!

    前言 最近在网上看到一个有意思的开源项目,基于快手团队开发的开源AI斗地主--DouZero做的一个"成熟"的AI,项目开源地址[https://github.com/tianqi ...

最新文章

  1. 【AI】caffe使用步骤(四):训练和预测
  2. Ajax实例(一)$.ajax的应用
  3. 浅谈视觉设计的准确性
  4. linux oracle 数据库导出
  5. 四阶龙格库塔法的基本思想_SIR模型计算基本再生数R0
  6. 电脑组装与维护教程_小白不会装机?教你如何自己组装一台电脑。装机图文教程...
  7. mysql存储过程打不开了_请问mysql存储过程的问题,我找了几个例子一个都运行不起来,...
  8. SCUT - 337 - 岩殿居蟹 - 线段树 - 树状数组
  9. react --- 隔代传递参数的三种方式
  10. php 输出01,php基础01_thinkphp输出Hello World-Go语言中文社区
  11. 每个Power BI开发人员的Power Query提示
  12. Qt 编码问题QTextCodec
  13. squid配置选项分析
  14. 单机到集群的WEB架构演变
  15. 关于图神经网络的相关学习资源的分享——网站 博客(一)
  16. 【博主推荐】HTML5响应式手机WEB(附源码)
  17. 如何在Android上查看本地空气质量指数
  18. 记录某次利用word邮件功能 由excel数据中批量生成奖状 遇到的问题及解决措施
  19. 华为轮值董事长郭平新年致辞:不经艰难困苦,何来玉汝于成
  20. 制作 macOS High Sierra U盘

热门文章

  1. 3年以上经验Java开发面试题
  2. 对灰色按钮克星的屏蔽
  3. vs2010+Silverlight4+wcf开发部署全过程
  4. 3D模型欣赏:美少女战士来袭!仙女水手水星请求出战!
  5. 时速云Kubernetes进阶培训 第三期
  6. 深入理解android卷2 豆瓣,豆瓣blog
  7. ESP8266开发之旅 进阶篇⑪ 深入了解 Esp8266 Https访问
  8. Python 项目打包各种依赖包
  9. Vue3配置路由ERROR in [eslint]报错问题
  10. Matlab遗传算法TSP求解