曾经收到过一份礼物,一个雪花飘落的程序,觉得效果很炫,通过前几篇的学习,我们已经掌握了贴图的一些技巧了,那么现在就可以自己实现了(当然你必须先拥有qt信号与槽的基础知识),这里先看效果,然后再分析如何实现。

效果图:

这个程序实现很久了,也是当初学习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

Qt实现桌面动态背景雪花飘落程序的更多相关文章

  1. 发布Qt Quick桌面应用程序的方法(使得planets在XP上运行)

    发布Qt Quick桌面应用程序的方法 Qt是一款优秀的跨平台开发框架,它可以在桌面.移动平台以及嵌入式平台上运行.目前Qt 5介绍程序发布的文章帖子比较少.大家又非常想要知道如何发布Qt应用程序,于 ...

  2. HTML5 canvas绘制雪花飘落动画(需求分析、知识点、程序编写分布详解)

    看到网上很多展示html5雪花飞动的效果,确实非常引人入胜,我相信大家也跟我一样看着心动的同时,也很好奇,想研究下代码如何实现:虽然哦很多地方也能下载这些源码,不过也不知道别人制作此类动画时的思路及难 ...

  3. 桌面应用开发之WPF动态背景

      因为项目需要,在WPF开发的桌面应用中,登陆页面需使用动态背景.由于没有前端开发人员,所以由半吊子的后端开发人员根据效果图写前端xaml.去掉页面上边框,抽离动态背景设置代码: <Windo ...

  4. 公布Qt Widgets桌面应用程序的方法

    公布Qt Widgets桌面应用程序的方法 Qt是一款优秀的跨平台开发框架,它能够在桌面.移动平台以及嵌入式平台上执行.眼下Qt 5介绍程序公布的文章帖子比較少.大家又很想要知道怎样公布Qt应用程序, ...

  5. 发布Qt Widgets桌面应用程序的方法(自定义进程步骤,用QT Creator直接生成)

    发布Qt Widgets桌面应用程序的方法 Qt是一款优秀的跨平台开发框架,它可以在桌面.移动平台以及嵌入式平台上运行.目前Qt 5介绍程序发布的文章帖子比较少.大家又非常想要知道如何发布Qt应用程序 ...

  6. 如何实现一个 windows 桌面动态壁纸

    ​ 更新: 2018/08/31 WS_MOUSE_LL 钩子,实现底层壁纸交互效果. 一.介绍 国内玩家第一次看到动态壁纸,都是出于一款来自 Wallpaper Engine 的 Steam 程序. ...

  7. 面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序

    面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序 Ajax 为更好的 Web 应用程序铺平了道路 在 Web 应用程序开发中,页面重载循环是最大的一个使用障碍,对于 Java™ ...

  8. Qt中设置widget背景颜色/图片的注意事项(使用样式表 setStyleSheet())

    在Qt中设置widget背景颜色或者图片方法很多种:重写paintEvent() , 调色板QPalette , 样式表setStyleSheet等等. 但是各种方法都有其注意事项,如果不注意则很容易 ...

  9. 手写简单的jq雪花飘落

    闲来无事,准备写个雪花飘落的效果,没有写太牛逼的特效,极大的简化了代码量,这样容易读取代码,用起来也很简单,对于那些小白简直是福利啊,简单易读易学.先直接上代码吧,然后再一一讲解,直接复制粘贴就可以拿 ...

随机推荐

  1. delphi ExecWB

    TWebBrowser.ExecWB 关键点 procedure ExecWB(cmdID: OLECMDID; cmdexecopt: OLECMDEXECOPT); overload; 实现过程 ...

  2. 关于android开发添加菜单XML文件之后无法在R.java中生成ID的问题

    因为和同学分开做的android软件,现在想整合他做的界面部分,于是拷贝了res和src文件夹的文件,其中包括一个res.menu文件夹中的XML.但是每次将该文件导入到工程总无法自动在R.java中 ...

  3. api.connectionType 判断当前网络技术经验

    使用  api.connectionType 判断当前网络的时候,需要注意,要加入大小写转换,三星返回的网络是大写 3G /** * 返回当前是否联网 * 周枫 * 3g 4g wifi none * ...

  4. 高级I/O之readn和writen函数

    管道.FIFO以及某些设备,特别是终端.网络和STREAMS设备有下列两种性质: (1)一次read操作所返回的数据可能少于所要求的数据,即使还没有达到文件尾端也可能是这样.这不是一个错误,应当继续读 ...

  5. UNIX基础知识之文件和目录

    程序清单1-1 列出一个目录中的所有文件(ls命令的简要实现): [root@localhost unix_env_advance_prog]# cat prog1-.c #include " ...

  6. discuz常用变量

    帖子URL: {url}帖子标题: {title}附件图片: {pic}帖子内容: {summary}楼主: {author}楼主UID: {authorid}楼主头像: {avatar}楼主头像(中 ...

  7. query插件之ajaxForm ajaxSubmit的理解用法

    如今ajax满天飞,作为重点的form自然也受到照顾. 其实,我们在平常使用Jquery异步提交表单,一般是在submit()中,使用$.ajax进行.比如:   $(function(){ $('# ...

  8. 嵌入式 Linux 应用:概述

    转载:http://www.ibm.com/developerworks/cn/linux/embed/embl/overview/index.html   从腕表到基于群集的超级计算机 在对嵌入式 ...

  9. BootStrap2学习日记3--响应式布局实用类

    BootStrap2中常用的响应式布局类如: visible-phone     仅在 手机平台显示 visible-tablet      仅在 平板电脑显示 visible-desktop   仅 ...

  10. ESX虚拟机文件列表详解

    http://jackiechen.blog.51cto.com/196075/210492 关闭状态时的文件列表: *-flat.vmdk:虚拟机的原始磁盘文件,包含整个虚拟机镜像.   *.nvr ...