圣诞节到了,写个桌面下雪的程序庆祝一下。过节也是要有仪式感的!!
显示效果如下:
具有如下功能:
完整代码和可执行程序下载:
可执行程序:
链接:https://pan.baidu.com/s/1zzL_grZa9fABeKXPOFKM0Q
提取码:567n
源码下载:
链接:https://pan.baidu.com/s/1CdvrCaeHa6YWeKkt8fszpw
提取码:df8t
这里下雪和烟花的效果都是用的QML实现的,其中烟花的效果可以参考这篇文章:
https://blog.csdn.net/yafeilinux/article/details/86530616
下雪的效果,使用的QML的粒子
下面贴出部分关键代码:
import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Particles 2.12 Rectangle { id: rootRect objectName: "rootRect" color: Qt.rgba(0, 0, 0, 0.01); ParticleSystem{ id: particleSystem objectName: "particleSystem" } Emitter { id: particleEmitter objectName: "particleEmitter" system: particleSystem anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter width: parent.width height: 1 emitRate: 10 lifeSpan: 10000 lifeSpanVariation: 100 size: 25 sizeVariation: 5 endSize: 20 velocity: CumulativeDirection { AngleDirection { objectName: "sonwVelocity" angle: 90 angleVariation: 10 magnitude: 200 magnitudeVariation: 20 } } acceleration: AngleDirection{ angle: 90 magnitude: 25 } } ImageParticle { system: particleSystem source: "file:///D:/Image/star.png" // alpha: 0 // colorVariation: 0.2 rotation: 0 rotationVariation: 10 rotationVelocity: 90 rotationVelocityVariation: 10 entryEffect: ImageParticle.Scale } Turbulence { system: particleSystem anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter width: parent.width height: parent.height / 2 strength: 100 } }
代码比较简单,就是一个创建了一个粒子发射器,发射粒子就可以了。
其中控制是否下雪、速度等是通过C++的代码控制的,这里以控制下雪的速度为例,简要进行说明:
// 下雪的速度 int ParticleWidget::getSnowSpeed(void) { QQuickItem* pRootItem = m_pQuickWidget->rootObject(); QObject* object = pRootItem->findChild<QObject*>("sonwVelocity"); // object->dumpObjectTree(); if (object == nullptr) return false; int value = (int)object->property("magnitude").toDouble(); return value; } void ParticleWidget::setSnowSpeed(int speed) { QQuickItem* pRootItem = m_pQuickWidget->rootObject(); QObject* object = pRootItem->findChild<QObject*>("sonwVelocity"); // object->dumpObjectTree(); if (object == nullptr) return; object->setProperty("magnitude", speed); }
在粒子发射器( Emitter )中的属性 velocity , 我们创建了一个objectName 为 sonwVelocity , 该对象的属性 magnitude 就是控制速度的属性。C++代码通过设置和获取该属性的值,从而获取和控制速度。 这里使用 findChild 函数,查找子元素。
Qt中的托盘也比较简单,使用类 QSystemTrayIcon 即可实现。
void ParticleConfig::initSystemTrayIcon(void) { m_pSystemTrayIcon = new QSystemTrayIcon(this); m_pSystemTrayIcon->setIcon(QIcon("./images/icon.png")); // 初始化菜单 QMenu* pMenu = new QMenu; // 设置 QAction* pConfigAction = new QAction(tr("Setting")); QObject::connect(pConfigAction, &QAction::triggered, this, &ParticleConfig::onClickedConfigAction); pMenu->addAction(pConfigAction); // 关于我 QAction* pAboutMeAction = new QAction(tr("About Me")); QObject::connect(pAboutMeAction, &QAction::triggered, this, &ParticleConfig::onClickedAboutMe); pMenu->addAction(pAboutMeAction); pMenu->addSeparator(); // 退出 QAction* pExitAction = new QAction(tr("Exit")); QObject::connect(pExitAction, &QAction::triggered, this, &ParticleConfig::onClickedExit); pMenu->addAction(pExitAction); m_pSystemTrayIcon->setContextMenu(pMenu); QObject::connect(m_pSystemTrayIcon, &QSystemTrayIcon::activated, \ this, &ParticleConfig::onActivated); m_pSystemTrayIcon->show(); }
函数 setContextMenu() 可以为托盘设置菜单。信号 activated 则可以响应双击等事件。
void ParticleConfig::onActivated(QSystemTrayIcon::ActivationReason reason) { if (reason == QSystemTrayIcon::DoubleClick) onClickedConfigAction(); }
实现代码如下:
m_pQuickWidget = new QQuickWidget; mainLayout->addWidget(m_pQuickWidget); m_pQuickWidget->setSource(QUrl("qrc:/main.qml")); m_pQuickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); m_pQuickWidget->setClearColor(Qt::transparent); this->setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Dialog); this->setAttribute(Qt::WA_TranslucentBackground); QTimer::singleShot(100, [&]()->void{ SetWindowLong((HWND)winId(), GWL_EXSTYLE, GetWindowLong((HWND)winId(), GWL_EXSTYLE) | WS_EX_TRANSPARENT//忽略一切消息(WM_PAINT除外) | WS_EX_LAYERED); });
预览: