曾經收到過一份禮物,一個雪花飄落的程序,覺得效果很炫,通過前幾篇的學習,我們已經掌握了貼圖的一些技巧了,那麼現在就可以自己實現了(當然你必須先擁有qt信號與槽的基礎知識),這裡先看效果,然後再分析如何實現。
效果圖:
1: //讓程序無邊框
2: setWindowFlags( Qt::FramelessWindowHint );
3: //讓程序背景透明
4: setAttribute(Qt::WA_TranslucentBackground, true);
2、建立雪花池、飄落、回收的聯動,形成一個循環系統
1: connect(&m_snowWait, SIGNAL(falling(SNOWLIST*)), &m_snowFalling, SLOT(AcceptSnow(SNOWLIST*)));2: connect(&m_snowFalling, SIGNAL(snowLander(SNOWLIST*)), &m_snowLander, SLOT(LanderSnow(SNOWLIST*)));3: connect(&m_snowLander, SIGNAL(snowRecycle(SNOWLIST*)), &m_snowWait, SLOT(SnowRecycle(SNOWLIST*)));
3、每一朵雪花我們可以用一個button來承載,並為每一朵雪花定義飄落的行為。
雪花節點頭文件:
1: #include <QToolButton>2: #include <QPropertyAnimation>3: class QPixmap;4: class QPaintEvent;5: class QPoint;6: class QSize;7:8: class SnowNode : public QToolButton9: {10: public:11: static const int MAXSWOW ;12: SnowNode(QWidget *parent = 0);13: QSize GetSnowSize();14: bool IsLander();15: void InitSnow();16: void FallingAnimation();17:18: protected:19: void paintEvent(QPaintEvent *event);20: private:21: QString GetImgFileName();22: private:23: QPixmap m_pixmap;24: QPropertyAnimation *m_animation;25: QSize m_areaSize;26: };
雪花節點實現文件:
1: #include "pubbase.h"2: #include "snownode.h"3: #include <QSize>4: #include <QPoint>5: #include <QBitmap>6: #include <QPixmap>7: #include <QToolButton>8: #include <QApplication>9: #include <QDesktopWidget>10: #include <QGraphicsScene>11: #include <QGraphicsView>12: const int SnowNode::MAXSWOW = 19;13:14: SnowNode::SnowNode(QWidget *parent):15: QToolButton(parent),m_animation(new QPropertyAnimation(this, "geometry"))16: {17: //必須設置為無邊框,否則可見區域和圖片繪制區域將出現不重疊18: setWindowFlags( Qt::FramelessWindowHint );19: resize(GetSnowSize());20: //對圖片進行縮放21: m_pixmap.load(GetImgFileName());22: m_pixmap = m_pixmap.scaled(this->size(),Qt::IgnoreAspectRatio);23: setHidden(true);24: m_areaSize.setWidth(QApplication::desktop()->width());25: m_areaSize.setHeight(QApplication::desktop()->height());26: }27:28: //初始化雪花29: void SnowNode::InitSnow()30: {31: this->move(qrand() % m_areaSize.width(), -32);32: }33:34: //設置雪花動畫35: void SnowNode::FallingAnimation()36: {37: int x = qrand()% m_areaSize.width();38: //雪花飄落全程時間39: m_animation->setDuration(8000);40: m_animation->setStartValue(QRect( pos(), size()));41: m_animation->setEndValue(QRect( QPoint(x,m_areaSize.height()), size()));42: m_animation->start();43: }44:45: //返回雪花是否已著陸46: bool SnowNode::IsLander()47: {48: if(this->pos().y() >= m_areaSize.height()49: && m_animation->state() == QAbstractAnimation::Stopped50: )51: {52: return true;53: }54: return false;55: }56:57: void SnowNode::paintEvent(QPaintEvent *event)58: {59: //繪制背景圖片60: this->setIcon(QIcon(m_pixmap));61: this->setIconSize(size());62: //將png圖片透明部分設置為穿透63: this->setMask(m_pixmap.mask());64: //繪制65: QToolButton::paintEvent(event);66:67: }68:69: //每一朵雪花的大小,采用隨機生成70: QSize SnowNode::GetSnowSize()71: {72: int x = qrand() % 10;73: return x >= 6 ? QSize(32,32) : x >= 3 ? QSize(24,24) : QSize(16,16);74: }75:76: //獲取雪花文件名77: QString SnowNode::GetImgFileName()78: {79: return QString().sprintf(":/image/_%d.png", qrand()% MAXSWOW);80: }81:
4、替換一個桌面背景
1: 調用windows API函數來設置桌面背景2: ::SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, (void*)imgFileName, SPIF_UPDATEINIFILE)
5、定義一個定時器,定時投放雪花即可
有想學習的盆友,可以留下你的郵箱地址,我會將完整的源碼發給你。