基于Qt的 动漫人物展示 替换桌面壁纸

学qt有一阵子,今天正好有闲心写篇博客。

项目介绍

写个展示动漫小姐姐的软件(图片资源网上找的)
效果如下
在这里插入图片描述

在这里插入图片描述
实现原理并不难。简单讲述一下思路。工具是用vs2022 cmake构建

一个主窗口 去除边框 窗口透明 然后支持拖。剩下的就是对界面进行美化用qss美化 (说实话美化比mfc方便多了,界面友好)。

最后附上软代码有兴趣的可以自己编译运行。当前项目使用的环境是QT5。 编译时更改一下qt路径即可。

代码展示

主程序代码

#include "MyDesktopSoft.h"
#include "eventfilterobject.h" 
#include <QResizeEvent>
#include <QTimer>
#include <QFile>
MyDesktopSoft::MyDesktopSoft(QWidget *parent):QWidget(parent)
{

	this->init_ui();
}

void MyDesktopSoft::updateRoleModelAnimation()
{
	m_frames = m_roleModels[m_currentRole].size();
	m_roleModelLabel->setPixmap(m_roleModels[m_currentRole][m_index]);
	
	m_index = (m_index + 1) % m_frames;
}

void MyDesktopSoft::init_ui()
{
	setFixedSize(350, 640);
	setWindowFlag(Qt::FramelessWindowHint); //取消窗口边框
	setWindowFlag(Qt::WindowStaysOnTopHint);//窗口置顶
	setAttribute(Qt::WA_TranslucentBackground);//窗口背景透明
	installEventFilter(new eventFilterObject(this)); // 捕获窗口拖拽

	//添加人物资源
	RoleModel roleModel;
	for (int i = 0; i < 6; i++) {
		roleModel.addFrame(QString(":/assets/desktopRole/blackGril/action1-happy/%1.png").arg(i));
	}
	m_roleModels.insert("blackGril/happy", roleModel);

	roleModel.clear();
	for (int i = 0; i < 6; i++) {
		roleModel.addFrame(QString(":/assets/desktopRole/blackGril/action2-sad/%1.png").arg(i));
	}
	m_roleModels.insert("blackGril/sad", roleModel);

	roleModel.clear();
	for (int i = 0; i < 6; i++) {
		roleModel.addFrame(QString(":/assets/desktopRole/blackGril/action3-naughty/%1.png").arg(i));
	}
	m_roleModels.insert("blackGril/naughty", roleModel);


	roleModel.clear();
	for (int i = 0; i < 6; i++) {
		roleModel.addFrame(QString(":/assets/desktopRole/blackGril/action4-shy/%1.png").arg(i));
	}
	m_roleModels.insert("blackGril/shy", roleModel);


	roleModel.clear();
	for (int i = 0; i < 6; i++) {
		roleModel.addFrame(QString(":/assets/desktopRole/littleBoy/%1.png").arg(i));
	}
	m_roleModels.insert("littleBoy", roleModel);

	roleModel.clear();
	for (int i = 0; i < 6; i++) {
		roleModel.addFrame(QString(":/assets/desktopRole/summerGril/%1.png").arg(i));
	}
	m_roleModels.insert("summerGril", roleModel);



	m_roleModelLabel = new QLabel(this);
	m_wallpaper = new Wallpaper;
	
	QTimer* timer = new QTimer(this);
	timer->callOnTimeout(this,&MyDesktopSoft::updateRoleModelAnimation);
	timer->start(600);

	m_currentRole = "summerGril"; //默认情况下是 summerGril
	updateRoleModelAnimation();

	m_closeBtn = new QPushButton(this);
	m_settingBtn = new QPushButton(this);

	m_closeBtn->move(240, 300);
	m_settingBtn->move(240, 340);
	m_closeBtn->setObjectName("closeBtn");
	m_settingBtn->setObjectName("settingBtn");

	QFile file(":/assets/style.css");
	if (file.open(QIODevice::ReadOnly)) {
		this->setStyleSheet(file.readAll());
	}
	m_setting = new Setting;
	connect(m_closeBtn, &QPushButton::released, this, &MyDesktopSoft::close);
	connect(m_settingBtn, &QPushButton::released, m_setting, &QWidget::show);

	//当主界面关闭时通知附界面关闭
	connect(m_closeBtn, &QPushButton::released, m_setting, &QWidget::close);

	//附属界面给主界面发送消息 模型更换了
	
	connect(m_setting, &Setting::roleModelChanged, this, [=](const QString& role) {
		m_currentRole = role;
		});

	connect(m_setting, &Setting::wallpaperChanged, m_wallpaper, &Wallpaper::setWallpaper);
}

MyDesktopSoft::~MyDesktopSoft()
{

	//申请的指针都要去释放 最后
	if (m_setting) {
		delete m_setting;
	}
	if (m_closeBtn) {
		delete m_closeBtn;
	}
	if (m_settingBtn) {
		delete m_settingBtn;
	}
	if (m_roleModelLabel) {
		delete m_roleModelLabel;
	}
	if (m_wallpaper) {
		delete m_wallpaper;
	}

}

void MyDesktopSoft::resizeEvent(QResizeEvent* ev)
{
	
	m_roleModelLabel->resize(ev->size());

}

void MyDesktopSoft::mousePressEvent(QMouseEvent* ev)
{


	if (ev->button() == Qt::MouseButton::RightButton) {
		m_closeBtn->setVisible(!m_closeBtn->isVisible());
		m_settingBtn->setVisible(!m_settingBtn->isVisible());
	}
	


}

响应鼠标拖拽 代码片段

#include "eventfilterobject.h"
#include<QMouseEvent>
#include<QWidget>
eventFilterObject::eventFilterObject(QObject *parent) : QObject(parent)
{

}

bool eventFilterObject::eventFilter(QObject *watched, QEvent *ev)
{
    auto* mouseEv = static_cast<QMouseEvent*>(ev);
    static QPoint dis;
    if(ev->type() == QEvent::MouseButtonPress)
    {
        dis = mouseEv->pos();
    }
    else if(ev->type() == QEvent::MouseMove && mouseEv->buttons()&Qt::LeftButton
            && !dis.isNull())
    {
        auto *pthis = static_cast<QWidget*>(watched);
        //if(pthis->parent()==nullptr)
        pthis->move(mouseEv->globalPos() - dis);
        //pthis->move(pthis->mapToParent(mouseEv->pos()) - dis);
    }
    else if(ev->type() == QEvent::MouseButtonRelease)
    {
        dis = QPoint();
    }
    return false;
}

查找顶层窗口类

头文件


#ifndef FINDDEKTOPHWND_H
#define FINDDEKTOPHWND_H
#include<qt_windows.h>
class QWidget;
class FindDektopHwnd
{
public:
    FindDektopHwnd();
    static BOOL CALLBACK EnumWindowsProc(_In_ HWND tophandle, _In_ LPARAM topparamhandle);
    /*
    * @return 返回桌面句柄
    */
    static HWND GetDesktopHandle();

    /**
     * @param child 是需要设置为子窗口的控件.
     * @param parent 是空则把child设置为桌面的孩子,否则设置为parent的孩子
     */
    static void SetParent(QWidget*child,HWND parent);

    inline static HWND _workerw = NULL;
};

#endif // FINDDEKTOPHWND_H

cpp文件

#include "finddektophwnd.h"
#include<QWidget>
FindDektopHwnd::FindDektopHwnd()
{

}

BOOL CALLBACK FindDektopHwnd::EnumWindowsProc(_In_ HWND tophandle, _In_ LPARAM topparamhandle)
{
    HWND defview = FindWindowExW(tophandle, 0, L"SHELLDLL_DefView", NULL);
    if (defview != NULL)
    {
        _workerw = FindWindowExW(0, tophandle, L"WorkerW", 0);
    }
    return true;
}//遍历句柄的回调函数

HWND FindDektopHwnd::GetDesktopHandle()
{
    ULONG_PTR result;
    HWND windowHandle = FindWindowW(L"Progman", NULL);
    SendMessageTimeout(windowHandle, 0x052c, 0, 0, SMTO_NORMAL, 0x3e8, (PDWORD_PTR)&result);
    EnumWindows(EnumWindowsProc, (LPARAM)NULL);
    ShowWindow(_workerw, SW_HIDE);
    return windowHandle;
}

void FindDektopHwnd::SetParent(QWidget *child, HWND parent)
{
    HWND dekstopHwnd = parent;
    if(parent == nullptr)
    {
        //获取桌面的窗口句柄
        dekstopHwnd = FindDektopHwnd::GetDesktopHandle();
    }

    //把dekstopHwnd设置为父对象
    ::SetParent((HWND)child->winId(),(HWND)dekstopHwnd);
}


身下的就是一些细碎处理事件

唉,剩下的代码就不一一展示了,都在附件中有需要的可以自提

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值