• Qt5开发从入门到精通——第七篇一节( 图形视图——动画效果 )


    欢迎小伙伴的点评✨✨,相互学习、互关必回、全天在线🍳🍳🍳
    博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩‍🚀


    前言

    本章将通过实现的例子介绍如何进行自定义 QGraphicsltem , 以及如何利用定时器来实现QGraphicsltem 动画效果 。


    一、QGraphicsScene 类概述

    它是一个用于放置图元的容器,本身是不可见的,必须通过与之相连的视图类来显示及与外界进行互操作。通过 QGraphicsScene: :addltem()可以添加 一个图元到场景中。图元可以通过多个函数进行检索。 QGraphicsScene: :items()和 一些重载函数可以返回与点、矩形、多边形或向量路径相交的所有图元。 QGraphicsScene: :itemAt()返回指定点的顶层图元。

    二、效果实例

    图一
    在这里插入图片描述

    添加图片到Resources中步骤如下:
    图二
    在这里插入图片描述
    图三
    在这里插入图片描述
    图四
    在这里插入图片描述


    三、原码解析

    butterfly.h

    #ifndef BUTTERFLY_H
    #define BUTTERFLY_H
    
    #include 
    #include 
    #include 
    #include 
    #include 
    class Butterfly : public QObject,public QGraphicsItem
    {
        Q_OBJECT
    public:
        explicit Butterfly(QObject *parent = nullptr);
        void timerEvent(QTimerEvent *);              //定时器实现动画的原理是在定时器的 timerEvent()中对QGraphicsItem 进行重绘。
        QRectF boundingRect () const;               //为图元限定区域范围,所有继承自 QGraphicsItem 的自定义图元都必须实现此函数。
    
    signals:
    public slots:
    protected:
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget); //重绘函数
    private:
         bool up;
         QPixmap pix_up;       //用于标志皮卡丘的位置(位于上或下),以便实现动态效果。
         QPixmap pix_down;     //用于保护图片
         qreal angle;
    public slots:
    };
    
    #endif // BUTTERFLY_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    butterfly.cpp

    #include "butterfly.h"
    #include 
    
    const static double PI=3.1416;
    
    Butterfly::Butterfly(QObject *parent) : QObject(parent)
    {
        up= true;                 //给标志图片位置的变量赋值
        pix_up.load(":/src/up.png");
        pix_down.load(":/src/down.png"); //调用 QPixmap 的 load() 函数加载所用到的图片
        startTimer(100);         //启动定时器,并设置时间间隔为 100 毫秒
    }
    QRectF Butterfly::boundingRect () const    //boundingRect() 函数为图元限定区域范围。此范围是以图元自身的坐标系为基础设定的。
    {
        qreal adjust =2;
        return QRectF (-pix_up. width() /2-adjust, -pix_up. height() /2-adjust,
        pix_up. width() +adjust*2, pix_up. height() +adjust*2);
    }
    
    /*在重画函数 paint()中,首先判断当前已显示的图片是 pix_up 还是 pix_down。实现皮卡丘
    上下飞舞效果时,若当前显示的是 pix_up 图片,则重绘 pix_down 图片,反之亦然。*/
    void Butterfly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
    {
        if(up)
        {
           painter->drawPixmap(boundingRect().topLeft(),pix_up);
           up=!up;
        }else
        {
            painter->drawPixmap(boundingRect() .topLeft(),pix_down);
            up=!up;
        }
    }
    
    void Butterfly::timerEvent(QTimerEvent *)   //定时器的 timerEvent()函数实现皮卡丘的飞舞
    {
        // 边界控制
        qreal edgex=scene () ->sceneRect () . right() +boundingRect () .width()/2;
                                              //限定图片飞舞的右边界
        qreal edgetop=scene()->sceneRect() .top()+boundingRect(). height()/2;
                                               //限定图片飞舞的上边界
        qreal edgebottom=scene () ->sceneRect () .bottom() +boundingRect ().height()/2;
                                              //限定图片飞舞的下边界
        if (pos ().x()>=edgex)      //若超过了右边界,则水平移回左边界处
        {
            setPos (scene()->sceneRect().left(),pos().y());
        }
        if (pos().y()<=edgetop)    //若超过了上边界,则垂直移回下边界处
        {
            setPos (pos().x() , scene()->sceneRect().bottom());
        }
        if(pos().y()>=edgebottom)   //若超过了下边界,则垂直移回上边界处
        {
            setPos(pos().x(),scene()->sceneRect() . top());
        }
    
        angle+= (qrand ()%10)/20.0;
        qreal dx=fabs(sin(angle*PI)*10.0);
        qreal dy= (qrand ()%20)-10.0;
        setPos(mapToParent(dx,dy));    /*完成皮卡丘随机飞行的路径,且 dx 、 dy 是相对皮卡丘
    的坐标系而言的,因此应使用 mapToParent() 函数映射为场景的坐标。*/
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    main.cpp

    #include "butterfly.h"
    #include 
    #include 
    int main(int argc, char *argv[])
    {
        //关联一个视图
        QApplication a(argc, argv);
        QGraphicsScene *scene= new QGraphicsScene;
        scene->setSceneRect(QRectF(-2-00,-200,400,400));
        Butterfly *butterfly= new Butterfly;
        butterfly->setPos(-100,0);
        scene->addItem(butterfly);
        QGraphicsView *view= new QGraphicsView;
        view->setScene(scene);
        view->resize(400,400);
        view->show();
    
    
        return a.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    四、总结

    图形视图的动画效果会在应用程序开发中经常用到的

  • 相关阅读:
    现代c++中实现精确延时方法总结
    对话大众软件子公司:中国的智舱、智驾比欧洲早一代
    LIS系统-实现检验报告集中管理
    webpack详解
    变量赋值中 + 号 - 号 = 号的用法
    史上最全MongoDB之Mongo Shell使用
    深入探析:云计算与边缘计算在软件开发中的应用与挑战
    面向防疫的智能导诊机器人关键技术及应用
    MySQL的锁这么多,不知从何学起,看完这篇文章就够了
    2023.10.02
  • 原文地址:https://blog.csdn.net/weixin_44759598/article/details/126862083