这个程序可以实现把图片、动图、视频当成壁纸显示在图标图层之下,软件会保存上一次关闭时的选择 重启时恢复,有什么问题评论区看到会回复
有问题欢迎指出,需要编译好的程序 可以私信或留下联系方式发送
废话不多说先上
效果
再上
代码
,核心代码我都打上了“关键”两字
静态图片:
动画壁纸:
视频壁纸 带有音频的话可以勾选壁纸音乐:
.pro文件内容
QT += core gui multimediawidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
RC_ICONS = ../image/tubiao.ico
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMenu>
#include <QMovie>
#include <QTimer>
#include <qlabel.h>
#include <QSettings>
#include <windows.h>
#include <QFileDialog>
#include <QVideoWidget>
#include <QMediaPlayer>
#include <QAudioOutput>
#include <QSystemTrayIcon>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
HWND winwallpaper();
HWND winwallpaper_send();
static inline BOOL CALLBACK enumwin(HWND han,LPARAM lp);
void mp4(QString fine); //显示视频
void gif(QString fine); //显示图片
//最小化托盘信号处理
void sys(QSystemTrayIcon::ActivationReason r);
QSystemTrayIcon* system;
//图片、视频类
QLabel* label;
QVideoWidget* vid;
QMediaPlayer* med;
QAudioOutput* aud = new QAudioOutput;
//使用此类记录使用状态
QSettings* ConfigFile;
private:
Ui::Widget *ui;
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
int if_sum = 1;
HWND win;
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
this->setWindowFlags(Qt::FramelessWindowHint);//去掉窗口边框
//this->setWindowTitle("动态壁纸"); //窗口标题 已去掉边框所以没有意义
//this->setWindowIcon(QIcon("image/tubiao.ico")); //窗口图标 已去掉边框所以没有意义
ConfigFile = new QSettings("config.cfg",QSettings::IniFormat);
//最小化托盘类指针
system = new QSystemTrayIcon(this);
ui->setupUi(this);
//动态壁纸按钮信号处理
connect(ui->gifButton,&QPushButton::clicked,this,[=]()
//获取文件路径与文件类型过滤器,返回文件路径
QString gifFile = QFileDialog::getOpenFileName(this,"打开动态图片","/","image(*.png *.jpg *.jpeg *.gif)");
//先关掉上一个窗口,不然无法在退出程序时关闭窗口
if(ConfigFile->value("GIF") == "正在使用")
label->close();
else if(ConfigFile->value("MP4") == "正在使用")
vid->close();
//将信息写入配置文件,待下次启动时初始化程序
ConfigFile->setValue("GIF","正在使用");
ConfigFile->setValue("GIF图片路径",gifFile);
ConfigFile->setValue("MP4","暂停使用");
//将文件路径传递给自定义图片显示函数
gif(ConfigFile->value("GIF图片路径").toString());
//视频壁纸按钮信号处理,同上
connect(ui->mp4Button,&QPushButton::clicked,this,[=]()
QString mp4File = QFileDialog::getOpenFileName(this,"打开视频文件","/","MV(*.mp4 *.wav *.mp3)");
if(ConfigFile->value("GIF") == "正在使用")
label->close();
else if(ConfigFile->value("MP4") == "正在使用")
vid->close();
ConfigFile->setValue("MP4","正在使用");
ConfigFile->setValue("MP4视频路径",mp4File);
ConfigFile->setValue("GIF","暂停使用");
mp4(ConfigFile->value("MP4视频路径").toString());
//最小化托盘右键处理
QAction* show = new QAction("显示",this);
connect(show,&QAction::triggered,this,[=]()
this->show();
QAction* clos = new QAction("退出",this);
connect(clos,&QAction::triggered,this,[=]()
//先关闭所有显示窗口,再关闭主程序,(可优化)退出程序时的小卡顿由此产生
label->close();
vid->close();
this->close();
//只有在第一次运行时显示主窗口,往后启动或 自启动将不显示
if(ConfigFile->value("显示窗口") == "否")
QTimer::singleShot(100,this,[=]()
this->hide();
QMenu* menu = new QMenu(this);
menu->addAction(show);
menu->addAction(clos);
system->setContextMenu(menu);
system->setToolTip("动态壁纸");
system->setIcon(QIcon("image/tubiao.ico"));
system->show();
ConfigFile->setValue("显示窗口","否");
//右上角隐藏程序按钮大小及图标,下方是此按钮信号处理
ui->closeapp->resize(16,16);
ui->closeapp->setStyleSheet("border-image:url(image/close.png)");
connect(ui->closeapp,&QPushButton::clicked,this,[=]()
this->hide();
QMenu* menu = new QMenu(this);
menu->addAction(show);
menu->addAction(clos);
system->setContextMenu(menu);
system->setToolTip("动态壁纸");
system->setIcon(QIcon("image/tubiao.ico"));
system->show();
if(if_sum)
system->showMessage("动态壁纸","已隐藏到最小化托盘");
if_sum = 0;
//最小化托盘左键双击信号处理,功能(显示主窗口)
connect(system,&QSystemTrayIcon::activated,this,&Widget::sys);
//壁纸音乐复选框信号处理
connect(ui->checkBox,&QCheckBox::clicked,this,[=]()
if(ui->checkBox->isChecked())
aud->setMuted(false); //这个类方法是实现实时开关音乐的关键
ConfigFile->setValue("壁纸音乐","开启");
aud->setMuted(true);
ConfigFile->setValue("壁纸音乐","关闭");
//使用上一次关闭时的参数初始化程序
if(ConfigFile->value("壁纸音乐") == "开启")
ui->checkBox->setChecked(true);
if(ConfigFile->value("MP4") == "正在使用")
mp4(ConfigFile->value("MP4视频路径").toString());
if(ConfigFile->value("GIF") == "正在使用")
gif(ConfigFile->value("GIF图片路径").toString());
Widget::~Widget()
delete ui;
* 下方三个方法都是实现壁纸的关键
* 1.获取桌面最顶层窗口句柄
* 2.发送信号至桌面最顶层窗口
* 3.遍历WorkerW窗口
HWND Widget::winwallpaper()
HWND hwnd = ::FindWindow(L"Progman",NULL);
return hwnd;
HWND Widget::winwallpaper_send()
int result;
HWND hwnd = ::FindWindow(L"Progman",NULL);
SendMessageTimeout(hwnd,0x52c,0,0,SMTO_NORMAL,0x3e8,(PDWORD_PTR)&result);
return hwnd;
WINBOOL Widget::enumwin(HWND han, LPARAM lp)
HWND def = ::FindWindowEx(han,0,L"SHELLDLL_DefView",NULL);
if(def!= 0)
win = FindWindowEx(0,han,L"WorkerW",0);
return true;
//关键代码!将窗口至于桌面最顶层窗口之下,随后播放多媒体
void Widget::mp4(QString fine)
winwallpaper_send();
EnumWindows(enumwin,(LPARAM)NULL);
ShowWindow(win,SW_HIDE);
vid = new QVideoWidget;
med = new QMediaPlayer;
med->setVideoOutput(vid);
vid->setWindowState(Qt::WindowMaximized);
vid->setWindowFlags(Qt::FramelessWindowHint);
vid->showFullScreen();
med->setSource(QUrl::fromLocalFile(fine));
med->setLoops(QMediaPlayer::Infinite);
aud->setMuted(true);
med->setAudioOutput(aud);
if(ConfigFile->value("壁纸音乐") == "开启")
aud->setMuted(false);
med->play();
SetParent((HWND)vid->winId(),winwallpaper());
vid->show();
//关键代码!将窗口至于桌面最顶层窗口之下,随后显示图片
void Widget::gif(QString fine)
winwallpaper_send();
EnumWindows(enumwin,(LPARAM)NULL);
ShowWindow(win,SW_HIDE);
QMovie* movie = new QMovie(fine);
label = new QLabel;
label->setWindowState(Qt::WindowMaximized);
label->setWindowFlags(Qt::FramelessWindowHint);
label->setMovie(movie);
label->setScaledContents(true);
movie->start();
SetParent((HWND)label->winId(),winwallpaper());
label->show();
void Widget::sys(QSystemTrayIcon::ActivationReason r)
if(r == QSystemTrayIcon::DoubleClick)
this->show();
今天突然想换桌面的壁纸 想换个动态,网上那些桌面壁纸软件不是收费就是广告一大堆,所以决定自己写一个,看到github上有这个代码于是自己动手参照修改了一下这是他的git地址 https://github。
通过Qt做一些GUI项目时,有时需要去展示一些gif动态图至界面,如果将显示动态图的操作一并放置在主线程,即窗口显示线程中时,当需要加载的动态图数量多、尺寸大时,同时拖动窗口有可能产生卡顿的现象,且动态图的显示也有可能会卡顿。因此考虑设置一个子线程专用于动态图的显示。Qt中多线程的实现主要有以下两种方式:(1)继承QThread类,重写run()方法(2)继承QObject类,通过movetoThread()方法实现本案例使用第(1)种方式实现动态图的多线程显示。......
通过实现一个动态的桌面背景小程序,来加强对Qt的paintEvent的理解与使用,以及一些小知识。
二.实现过程
1. 初始化,并保存每段圆弧的起始度数和扫过的弧度,便于绘制圆弧。
//记录二十一个圆的圆弧信息
for(int i=0;i<21;i++)
vector<double> td; //存放一个圆里面圆弧的起始度数
vector<double> pd; //存放一个圆里面圆弧扫过的度数