Qt實現桌面動態背景雪花飄落程序


        曾經收到過一份禮物,一個雪花飄落的程序,覺得效果很炫,通過前幾篇的學習,我們已經掌握了貼圖的一些技巧了,那么現在就可以自己實現了(當然你必須先擁有qt信號與槽的基礎知識),這里先看效果,然后再分析如何實現。

效果圖:

image

 

       這個程序實現很久了,也是當初學習qt的時候寫的,因為工作的原因,當初的部分設想,並沒有全部實現,現在分享,供大家一起學習。

        當初的設想:

                1、雪花隨機飄落

                2、地面的花草,可以支持自由的move操作

                3、地面的植物可以積聚到雪花。

因為工作的原因,第3點並沒有實現,有興趣的可以自己實現,接下來講解一下實現步奏。

 

  實現方案:
    1、SnowNode雪花節點類,定義雪花的形狀、初始化狀態、行為
    2、WaitFallen待飄落的雪花類,用於定時向屏幕投入雪花
    3、Snowfalling 正在飄落的雪花,定時掃描雪花是否到達地上,雪花到達地上時,發送信號
    4、Snowpack 地上的積雪,定時將積雪回收
    5、GroundLife 地面物體
        Vegetable 植物
    6、SnowFrame雪花畫面,對雪花進行統一管理

功能插件:
    PngButton      圖片按鈕
    WidgetMove     普通的按鈕移動
    Virtual3DMove  將按鈕虛擬成三維效果,按鈕移動時進行放大和縮小
變量收集:
    雪花池數量: 200
    向屏幕投送雪花間隔: 1000
    每次投送雪花數量:0-5
    雪花飄落全程時間:10秒

 

 

關鍵點實現:

1、主窗體設置

  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 QToolButton
  9: {
 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::Stopped
 50:             )
 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、定義一個定時器,定時投放雪花即可

 

源碼地址:https://gitee.com/lingluonianhua/snow.git


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM