- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Python做个自定义动态壁纸还可以放视频由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前段时间,用PyQt5写了几篇文章,自己用python做的一款超炫酷音乐播放器、用Python做个个性的动画挂件让桌面不单调、详细过程带你用Python做车牌自动识别系统。今天就继续给大家分享一个实战案例,带大家一起用Python的PyQt5开发一个自定义动态桌面壁纸,好玩又有趣! 。
首先一起来看看最终实现的自定义动态壁纸效果:
下 。
面,我们开始介绍这个自定义动态桌面的制作过程.
。
总体来说,我们需要实现将自己喜欢的视频转成一个动态桌面,知识点主要包含了对视频提取解析,视频轮播,PyQt5窗体设置,桌面句柄获取,自定义动态桌面壁纸实现等.
拆解需求,大致可以整理出我们需要分为以下几步完成:
。
之前有粉丝反馈说,想自己跟着文章自己敲敲代码,但是不知道具体需要哪些模块、包文件,后面我就把所有用到模块先放出来.
import osimport sysfrom subprocess import callfrom threading import Threadfrom time import sleepimport cv2from PyQt5 import QtCore, QtWidgetsfrom PyQt5.QtCore import Qt, QTimerfrom PyQt5.QtGui import QImage, QPixmap, QIconfrom PyQt5.QtWidgets import QGridLayout, QPushButton, QMainWindow, QFileDialog, QLabel, QSystemTrayIcon, \ QAction, QMenu, QMessageBoxfrom os import path as pathq
。
根据动态壁纸所需要的功能,首先进行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.translate MainWindow.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布局设计完成,下面我们开始进行视频读取加载、预览功能实现.
。
接来下我们可以根据自己喜欢的视频,从本地读取视频,并且将视频预览播放显示。这里视频演示,博主还是用之前的那篇紫颜小姐姐的跳舞视频进行演示.
读取视频:
读取视频我们可以通过打开文件对话框,选择视频资源,开启一个子线程用来进行视频开启停止播放。核心代码如下:
# author: CSDN-Dragon少年def openmp4(self): try: global path path, filetype = QFileDialog.getOpenFileName(None, "选择文件", '.', "视频文件(*.AVI;*.mov;*.rmvb;*.rm;*.FLV;*.mp4;*.3GP)") # ;;All Files (*) if path == "": # 未选择文件 return self.slotStart() t = Thread(target=self.Stop) t.start() # 启动线程,即让线程开始执行 except Exception as e: print (e)
视频流读取播放:
接下来,我们需要对视频文件进行按帧读取加载显示,并通过计时器实现动画效果。核心代码如下:
# author:CSDN-Dragon少年def slotStart(self): videoName = path if 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.frame self.label_num.setText("There are " + str(5) + " people.") height, width, bytesPerComponent = frame.shape bytesPerLine = bytesPerComponent * width q_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() # 停止计时器
至此,我们已经可以实现视频读取加载,并且进行视频预览了,效果如下:
。
实现桌面壁纸替换,我们首先需要获取桌面句柄找到桌面窗体,覆写桌面窗体、调用加载的视频流,播放动态壁纸.
获取桌面句柄:
# author:CSDN-Dragon少年def pretreatmentHandle(): hwnd = win32gui.FindWindow("Progman", "Program Manager") win32gui.SendMessageTimeout(hwnd, 0x052C, 0, None, 0, 0x03E8) hwnd_WorkW = None while 1: hwnd_WorkW = win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None) if not hwnd_WorkW: continue hView = win32gui.FindWindowEx(hwnd_WorkW, None, "SHELLDLL_DefView", None) # print('hwmd_hView: ', hView) if not hView: continue h = win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None) while h: win32gui.SendMessage(h, 0x0010, 0, 0) # WM_CLOSE h = win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None) break return 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) return with 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: pass os.system('start play.exe') except: pass try: 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
这样,我们就完成了动态壁纸加载应用功能了,效果如下:
。
最后我们再实现下当前动态壁纸播放关闭功能,我们需要对当前桌面视频播放进行释放取消。代码如下:
# author:CSDN-Dragon少年 def close_wall(self): try: call('taskkill /F /IM play.exe') except: pass
效果如下:
至此,整个自定义动态桌面壁纸功能就全部完成了,下面我们一起运行下看看动态壁纸效果.
今天我们就到这里,明天继续努力! 。
到此这篇关于Python做个自定义动态壁纸还可以放视频的文章就介绍到这了,更多相关Python动态视频壁纸内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.csdn.net/hhladminhhl/article/details/119902562 。
最后此篇关于Python做个自定义动态壁纸还可以放视频的文章就讲到这里了,如果你想了解更多关于Python做个自定义动态壁纸还可以放视频的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
这个问题在这里已经有了答案: Difference between Property and Field in C# 3.0+ (10 个答案) 关闭 10 年前。 我不明白静态属性之间的区别: p
当元素被拖放时,有没有办法从被拖动的元素中获取 id(或其他属性值)? 例如,在左侧,我有一堆 div,我可以将图像放入其中。右边有一个 div 用来保存图像。当我将图像从右侧拖动到左侧的 div 时
每当我更改其中一个类属性时,我想设置一个修改标志,如下所示 public bool Modified { get; set; } public bool Enabled { get; set { Mo
由于某种原因,我下面的代码曾经可以正常工作,但现在却引发了一个异常: public static async Task HttpPut(string inUrl, string inFilePath)
为什么将 ; 放在最佳实践中?在函数定义的末尾。 例如 var tony = function () { console.log("hello there"); }; 优于: var tony
我在容器内有一个位图。当我拖动容器时,光标变为编辑文本形状,图像也跳到光标的右下角(好像我从左上角拿着图像并拖动它)。 这是我的代码,所以你可以看到我有 RTFM: function createIc
这个问题已经有答案了: C# 3.0 auto-properties — useful or not? [closed] (17 个回答) 已关闭 6 年前。 当我让 Visual Studio 20
以类中的以下代码为例: public class Employee : IEntity { public string FirstName { get; set; } public s
我有 json 数据: { "products": [ { "productId" : 0, "productImg" : "../img/product-ph
这个问题在这里已经有了答案: What is the difference between a field and a property? (33 个答案) 关闭 9 年前。 我在一本书上找到这样声
我正在设置多个方法,想知道如何继续将一个变量(“顶部”变量)传递给不同的方法。 主要方法: public static void Main(string[] args) { i
我正在尝试使用 crontab 编写一个简单的任务,将一些文件从本地复制到 HDFS。我的代码是这样的: #!/bing/ksh ANIO=$(date +"%Y") MES=$(date +"%m"
有人可以告诉我如何使用这个解决方案来解决我的问题吗?我也想限制 id 中包含文本“not”的节点的拖/放。 jsTree drag and drop restrict folders by class
我的情况如下 - 我正在对可能包含链接行的表进行排序: row 1 row 2 row 3 row 4 row 5 我需要的是禁止在.linked-to-p
我想知道是否有人知道是否有一个预先制定的解决方案:我在 ASP.net 网站上有一个列表,我希望用户能够通过拖放对列表进行重新排序。此外,我希望有第二个列表,用户可以将第一个列表中的项目拖到其中。 到
我在理解似乎不一致的方案中的破坏性操作时遇到问题。即为什么下例中bar没有变化 (define foo '(a b)) (define bar foo) (set! foo '(c d)) foo >
我想知道是否有人知道是否有一个预先制定的解决方案:我在 ASP.net 网站上有一个列表,我希望用户能够通过拖放对列表进行重新排序。此外,我希望有第二个列表,用户可以将第一个列表中的项目拖到其中。 到
我在理解似乎不一致的方案中的破坏性操作时遇到问题。即为什么下例中bar没有变化 (define foo '(a b)) (define bar foo) (set! foo '(c d)) foo >
我在我的 Web 应用程序中使用 Ajax ControlToolkit 中的 ModalPopupExtender。我将其 Drag 属性设置为 true,但是当我拖动弹出面板并将其放到新位置时,它
所以,基于this answer ,我有一组可以拖放并卡入到位的 div。唯一的问题是,可拖动的 div 具有不同的高度,我需要它们始终捕捉到目标的底部,而不是顶部。 您可以在this JsFiddl
我是一名优秀的程序员,十分优秀!