Qt 实现桌面雪花飘落

时间:2022-12-21 21:49:40

这两天无意发现有人写了VC等开发的桌面雪花飘落的程序, 我也写了一个, 算是也过上了剩蛋吧!

代码很简单, 贴个主要的实现过程吧. 理应支持windows和linux桌面版的, 但是linux下就暂时不测试了. 懒得重启. 有空测试一下.

系统资源消耗: 我在1.65GHz 双核CPU, 4G RAM, 32bit Win7 下, 19M左右的内存消耗, 6%-7%左右的CPU消耗.

全部源码在后面的链接.

#include "widget.h"
#include "ui_widget.h"
#include <QDesktopWidget>
#include <QPalette>
#include <QBrush>

#include <time.h>

#ifdef Q_OS_LINUX
#include <X11/extensions/shape.h>
#endif
#ifdef Q_OS_WIN
#include <windows.h>
#endif

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setGeometry(0, 0, qApp->desktop()->width(), qApp->desktop()->height());
setWindowFlags(windowFlags()
|Qt::FramelessWindowHint //去边框
|Qt::X11BypassWindowManagerHint //linux下脱离任务管理器
|Qt::WindowStaysOnBottomHint //最低层显示
|Qt::Tool //不在任务栏显示
);
setAttribute(Qt::WA_TranslucentBackground);
setWindowState(Qt::WindowNoState //不激活
|Qt::WindowFullScreen //全屏
);
setFocusPolicy(Qt::NoFocus);
setWindowOpacity(WINDOW_OPACITY);
#ifdef Q_OS_LINUX
XShapeCombineRectangles(QX11Info::display(), winId(), ShapeInput, 0,
0, NULL, 0, ShapeSet, YXBanded);
#endif
#ifdef Q_OS_WIN
SetWindowLong(winId(), GWL_EXSTYLE, GetWindowLong(winId(), GWL_EXSTYLE) |
WS_EX_TRANSPARENT | WS_EX_LAYERED);
#endif
int i=0;
pixmapList[i++].load(":/snowIcons/11.png");
pixmapList[i++].load(":/snowIcons/03.png");
pixmapList[i++].load(":/snowIcons/06.png");
pixmapList[i++].load(":/snowIcons/08.png");
pixmapList[i++].load(":/snowIcons/10.png");
pixmapList[i++].load(":/snowIcons/12.png");
pixmapList[i++].load(":/snowIcons/13.png");
pixmapList[i++].load(":/snowIcons/16.png");
pixmapList[i++].load(":/snowIcons/17.png");
pixmapList[i++].load(":/snowIcons/18.png");
pixmapList[i++].load(":/snowIcons/19.png");

for(i = 0; i < MAX_PICS; i++)
{
picLabel[i] = new QLabel(this);
picLabel[i]->setGeometry(-128, -128, 64, 64);
}
startTimer(150);
}

Widget::~Widget()
{
delete ui;
}

void Widget::timerEvent(QTimerEvent *e)
{
const int timeinit = 10;
static int timeCount = timeinit;
static int initLabel = MAX_PICS;
if(--timeCount <= 0)
{
qsrand(::time(NULL));
timeCount = timeinit;
if(initLabel > 0)
{
--initLabel;
picLabel[initLabel]->move(0, -picLabel[initLabel]->height());
}
}
FlashSnow();
}

void Widget::SetLabelBG(const QPixmap &pixmap, QLabel *label)
{
if(!label || pixmap.isNull()) return;
QPixmap map = pixmap.scaled(label->size());
if(map.isNull()) return;
label->setPixmap(map);
}

void Widget::FlashSnow()
{
int i;
for(i = 0; i < MAX_PICS; i++)
{
if(picLabel[i] == NULL) continue;
if(picLabel[i]->y() == -picLabel[i]->height())
{
//resize label
int size = (qrand()%64)+16;
picLabel[i]->resize(size, size);

//init place
int x = (qrand()%this->width());
picLabel[i]->move(x, 10-picLabel[i]->height());

//repaint label's backgroud
int imgId = (qrand()%MAX_PIXMAP);
SetLabelBG(pixmapList[imgId], picLabel[i]);
}
else
{
//snow flow down
WidgetFlowDown(picLabel[i]);
}
}
}

void Widget::WidgetFlowDown(QWidget *widget, bool bRandom)
{
if(!widget) return;
int downY = widget->y()+5;
if(bRandom)
{
downY = widget->y()+qrand()%(this->height() - widget->y());
}
if(downY > (this->height())) downY = -widget->height();
widget->move(widget->x(), downY);
}

接下来上个截屏吧:

Qt 实现桌面雪花飘落


最后是全部源码了, 是个Qt creator 工程:

工程压缩包下载: http://download.csdn.net/detail/vince025/6766537