• 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

  • 相关阅读:
    js学习总结----js中的三个判断
    js学习总结----js中的变量和数据类型
    js学习总结---js组成和命名规范
    ES6-----学习系列十八(模块化)
    ES6-----学习系列十七(Decorator)
    ES6-----学习系列十六(Generator)
    迭代器和for-of循环 顺便带一下Es5中的.map遍历
    Pc端css初始化
    css3常用属性
    css布局一屏幕的自适应高度
  • 原文地址:https://www.cnblogs.com/lingluotianya/p/4430379.html
Copyright © 2020-2023  润新知