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

这篇具有很好参考价值的文章主要介绍了桌面太单调?一起用Python做个自定义动态壁纸,竟然还可以放视频!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

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

首先一起来看看最终实现的自定义动态壁纸效果:
桌面太单调?一起用Python做个自定义动态壁纸,竟然还可以放视频!
下面,我们开始介绍这个自定义动态桌面的制作过程。

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

一、核心功能设计

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

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

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

二、实现步骤

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

import os
import sys
from subprocess import call
from threading import Thread
from time import sleep

import cv2
from PyQt5 import QtCore,  QtWidgets
from PyQt5.QtCore import Qt,  QTimer
from PyQt5.QtGui import QImage, QPixmap, QIcon

from 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.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实现效果如下:
桌面太单调?一起用Python做个自定义动态壁纸,竟然还可以放视频!
UI布局设计完成,下面我们开始进行视频读取加载、预览功能实现。

2. 视频加载预览

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

读取视频:

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

# 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()  # 停止计时器

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

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

3. 动态壁纸功能实现

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

获取桌面句柄:

# 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

这样,我们就完成了动态壁纸加载应用功能了,效果如下:
桌面太单调?一起用Python做个自定义动态壁纸,竟然还可以放视频!

4. 关闭动态壁纸

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

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

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

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

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

Python往期精彩:

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

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

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

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

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

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

  • 一起用Python做个自动化弹钢琴脚本,我竟然弹出了《天空之城》!
    往期精彩源码均可通过下方公众号获取
    文章来源地址https://www.toymoban.com/news/detail-425059.html

到了这里,关于桌面太单调?一起用Python做个自定义动态壁纸,竟然还可以放视频!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SV-8004VP 网络对讲求助话筒,4个自定义按键

    SV-8004VP网络对讲求助话筒 , 4个自定义按键 SV-8004VP是一款4按键求助对讲话筒,具有10/100M以太网接口,支持G.711音频编解码,其接收SIP网络的音频数据,实时解码播放,还配置了麦克风输入和扬声器输出。 SV-8004VP可以通过麦克风或者本地线路输入对SIP终端进行点对点的SIP对讲

    2024年01月16日
    浏览(38)
  • uniapp/H5 获取手机桌面壁纸 (静态壁纸)

    找半天没找到相关的内容,自己捣鼓出来的,记录一下。 (比较可惜的是只能获取静态图片,动态壁纸就不知道了咋弄了) uniapp的话还可以参考一下如何用NJS获取手机桌面壁纸? - DCloud问答下面DCloud_heavensoft 大佬的一个回答 : “Native.js很多类型没有。用uts可以 https://uni

    2024年02月19日
    浏览(38)
  • 电脑桌面壁纸不清晰?壁纸模糊怎么修复高清?

    我们在入手新电脑之后,首先就是会想要设置一个好看的壁纸,虽然系统会自带一些壁纸,但大多数用户都不喜欢这样一成不变的壁纸。于是在网上找了很好好看的壁纸换上,结果发现在更换电脑壁纸之后却发现壁纸显示非常的模糊不清。为什么桌面壁纸模糊不清呢?又要如

    2024年02月08日
    浏览(47)
  • 红队版goby-poc,包含447个自定义goby-poc

    下载地址:https://github.com/MY0723/goby-poc 下载有用的话给GitHub点个关注➕star谢谢喽🍖!! 包含447个自定义goby-poc,可能会有个别重复自行判断,来源于网络收集的GobyPOC,实时更新。 如果无红队版,可直接poc管理处导入自定义poc即可,共计745个。 本程序仅供于学习交流,请使用者遵

    2024年02月11日
    浏览(37)
  • 【二】一起算法---队列:STL queue、手写循环队列、双端队列和单调队列、优先队列

    纸上得来终觉浅,绝知此事要躬行。大家好!我是霜淮子,欢迎订阅我的专栏《算法系列》。 学习经典算法和经典代码,建立算法思维;大量编码让代码成为我们大脑的一部分。 ⭐️已更系列  1、基础数据结构        1.1、链表➡传送门        1.2、队列➡本章 专栏直达

    2023年04月08日
    浏览(54)
  • Android 12中系统Wallpaper详解1--锁屏透看壁纸和桌面透看壁纸的切换

    先看桌面情况下壁纸,这个情况应该属于我们最为熟悉的,那么就不用多说,大概就是因为桌面Activity的配置主题xml设置一个类似showallpaper的属性既可以,就可以让桌面后面显示壁纸了 2 aosp编译后版本锁屏后点亮屏幕也可以看到桌面壁纸(注意这里还不是专门锁屏壁纸) 大家

    2023年04月19日
    浏览(232)
  • 电脑怎么设置动态壁纸?关于Windows和Mac壁纸的设置方法

    为了让电脑桌面更加美观舒适,很多人都会给电脑的桌面设置自己喜欢的壁纸。 图片壁纸很多人都会设置,但是电脑怎么设置动态壁纸? 这是很多人的困扰。其实方法同样很简单,下面有关于Windows和Mac动态壁纸的设置方法,一起来看看! 操作环境: 演示机型:联想小新A

    2024年02月09日
    浏览(42)
  • QT开发实战-动态壁纸软件

    项目源代码在下面链接获取: ----------------------------- 开发者:CodeSharkSJ 希望此项目能加强你对Qt的应用 文章目录 项目图与开发环境 核心技术原理 自定义窗口程序 UI布局 背景绘制 样式表 基本实现 QWebEngine QMedia使用 系统托盘隐藏 记忆功能 应用程序打包 开发环境: visual studio 2

    2024年02月05日
    浏览(51)
  • 壁纸小程序Vue3(自定义头部组件)

     coustom-nav  1)状态栏     view class=\\\"statusBar\\\" :style=\\\"{height: statusBarHeight +\\\'px\\\'}\\\"/view H5中为0     view class=\\\"titleBar\\\" :style=\\\"{height:titleBarHeight+\\\'px\\\'}\\\" 获取胶囊位置   view class=\\\"fill\\\" :style=\\\"{height:statusBarHeight+titleBarHeight+\\\'px\\\'}\\\"     /view 填充区域,让轮播图展示全 script setup import { ref } from \\\'vue

    2024年04月11日
    浏览(33)
  • 一个.Net Core开发的开源动态壁纸软件

    推荐一个Github上Start超过10.8K的超火、好用、强大的、内置很多优美的动态壁纸软件。 这是基于.Net Core+WPF开发的、开源的动态壁纸软件,壁纸设置支持任何文件形式,包括:本地视频、网络视频、图片、Html、网络、Unity单机游戏、Godot游戏等;还支持自定义壁纸的属性,自定

    2024年02月05日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包