圣诞节到了,写个桌面下雪的程序庆祝一下。过节也是要有仪式感的!!
显示效果如下:
具有如下功能:
- 托盘菜单,可以配置、关于作者、退出。
- 可以配置是否下雪、烟花效果,配置雪的浓度和下降的速度。
完整代码和可执行程序下载:
可执行程序:
链接:https://pan.baidu.com/s/1zzL_grZa9fABeKXPOFKM0Q
提取码:567n
源码下载:
链接:https://pan.baidu.com/s/1CdvrCaeHa6YWeKkt8fszpw
提取码:df8t
1. 下雪的实现
这里下雪和烟花的效果都是用的QML实现的,其中烟花的效果可以参考这篇文章:
https://blog.csdn.net/yafeilinux/article/details/86530616
下雪的效果,使用的QML的粒子
下面贴出部分关键代码:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Particles 2.12Rectangle {id: rootRectobjectName: "rootRect"color: Qt.rgba(0, 0, 0, 0.01);ParticleSystem{id: particleSystemobjectName: "particleSystem"}Emitter {id: particleEmitterobjectName: "particleEmitter"system: particleSystemanchors.top: parent.topanchors.horizontalCenter: parent.horizontalCenterwidth: parent.widthheight: 1emitRate: 10lifeSpan: 10000lifeSpanVariation: 100size: 25sizeVariation: 5endSize: 20velocity: CumulativeDirection {AngleDirection {objectName: "sonwVelocity"angle: 90angleVariation: 10magnitude: 200magnitudeVariation: 20}}acceleration: AngleDirection{angle: 90magnitude: 25}}ImageParticle {system: particleSystemsource: "file:///D:/Image/star.png"
// alpha: 0
// colorVariation: 0.2rotation: 0rotationVariation: 10rotationVelocity: 90rotationVelocityVariation: 10entryEffect: ImageParticle.Scale}Turbulence {system: particleSystemanchors.left: parent.leftanchors.verticalCenter: parent.verticalCenterwidth: parent.widthheight: parent.height / 2strength: 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 函数,查找子元素。
2. 托盘
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();
}
3. 窗口透明
实现代码如下:
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);});
微信公众号:不会飞的纸飞机
不定时更新技术文章