项目背景:主要是想做一个AGV调度仿真软件,第一阶段先完成小车的运动先。所以需要学习一下QT的动画效果,为整个软件打下基础,
在这里插入图片描述
动画框架是由基类QAbstractAnimation和它的两个派生类QVariantAnimation、QAnimaitonGroup组成的。动画框架进一步提供了QProPertyAnimation类用于单个控件属性的变化,QAnimationGroup用于多动画的类。这篇文章主要讲解单个动画的实现。

在Qt Creator新建Qt Widgets Application,选择以QWidget为基础类。
在这里插入图片描述

接下来的代码在widget.cpp中的Widget函数实现。在这里插入图片描述

QPropertyAnimation

property是属性,animation是动画,所以这个类是专门用于控制控件属性的动画。QPropertyAnimation类继承QVariantAnimation类,能够修改Qt的属性值,如pos、geometry等属性。而动画的控件必须是QObject类的派生类,其实大部分控件都是QObject的派生类。我们可以通过指定属性的初始值和终值,比如初始的大小和结束的大小,初始的位置和结束的位置,初始的颜色和结束的颜色等。如果未指定初始值,属性就会被设定为生成控件实例时那个值。

头文件

前两个是工程建好就有的,第三个是为了新建按钮,第四个是为了新建动画。
在这里插入图片描述

坐标系

以下表示位置的坐标系定义如下图所示。
在这里插入图片描述

实现动画的简单步骤

1.实例化QPropertyAnimation对象。
2.绑定要实现动画的对象,该对象要继承于QObject父类。
3.设置要进行变化的属性,尺寸、位置‘颜色等。
4.设置属性的起始值和终止值。
5.设置动画运行时长。
6.启动动画。
下面的示例都具有这六个步骤。而实例化对象、绑定对象、设置属性有两种方式进行操作。
第一种方式是直接通过构造函数一步到位,如下图所示。在这里插入图片描述
第二种方式是分开进行,如下图所示。先实例化对象命名为Anima,然后通过setTargetObject函数和setPropertyName函数进行后两步。quit是一个创建好指向按钮的指针。
在这里插入图片描述

缩放

通过修改控件的geometry属性可以实现缩放效果,也可以实现位移的动画,该属性的前两个值确定了控件左上角的位置,后两个值确定了控件的大小。必须用QRcet来表示,有两种表示方式。我们选择第一种。
在这里插入图片描述
前面创建了一个QPushButton对象,用于动画的演示效果。setDuration设定的是动画的时间。
在这里插入图片描述

位移

如果只是需要位移动画的话,修改控件的pos属性即可。pos属性就是控件的左上角所在的位置。QPoint表示的是某一个点。
在这里插入图片描述

动画速度曲线

动画运动的速度曲线是可以更改的,默认是匀速运动。通过其成员函数setEasingCurve函数可以实现更改速度曲线的功能。在说明手册可以看到曲线的取值有哪些。

Anima->setEasingCurve(QEasingCurve::InOutQuad);

在这里插入图片描述
第一个Linear是默认的线性运动,速度是保持一定的。第二个InQuad曲线是二次函数曲线。下面还有很多,我就不列举了。可以通过一下方式查看曲线的取值。
鼠标放在函数处,按键盘上的F1;
在这里插入图片描述
再按一下红色框部分,就可以跳转到曲线介绍那里。
在这里插入图片描述

演示

通过信号与槽机制,建立按键与动画之间的联动关系,实现演示效果。代码如下:

#include "widget.h"
#include "ui_widget.h"

#include <QPushButton>
#include <QPropertyAnimation>
#include <QMessageBox>

 QPropertyAnimation *Anima = new QPropertyAnimation;
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //定义一个按键
    QPushButton *button1 = new QPushButton("缩放",this);
    //将点击信号关联到槽函数
    connect(button1,SIGNAL(pressed()),this,SLOT(suofang()));
    button1->setGeometry(20,20,100,40);

    QPushButton *button2 = new QPushButton("位移(默认曲线)",this);
    connect(button2,SIGNAL(pressed()),this,SLOT(ChangePos()));
    button2->setGeometry(130,20,100,40);

    QPushButton *button3 = new QPushButton("位移(Cubic曲线)",this);
    connect(button3,SIGNAL(pressed()),this,SLOT(ChangePos2()));
    button3->setGeometry(240,20,100,40);

    QPushButton *quit= new QPushButton("A",this);
    quit->setGeometry(10,200,30,30);
    Anima->setTargetObject(quit);




}

Widget::~Widget()
{
    delete ui;
}


void Widget::suofang()
{
    Anima->setPropertyName("geometry");
    Anima ->setDuration(1000);
    Anima ->setStartValue(QRect(10,200,10,10));
    Anima ->setEndValue(QRect(10,200,200, 200));
    Anima ->start();
}

void Widget::ChangePos()
{
    Anima->setPropertyName("pos");
    Anima ->setDuration(1000);
    Anima ->setStartValue(QPoint(10,200));
    Anima ->setEndValue(QPoint(500,200));
    Anima ->start();
}

void Widget::ChangePos2()
{
    Anima->setPropertyName("pos");
    Anima ->setDuration(1000);
    Anima ->setStartValue(QPoint(10,200));
    Anima ->setEndValue(QPoint(500,200));
    Anima->setEasingCurve(QEasingCurve::InOutCubic);
    Anima ->start();
}


槽函数必须要在widget.h进行函数声明。
在这里插入图片描述
请添加图片描述
通过演示,可以明显看到默认速度曲线和Cubic曲线运动的不同。

插值运动

前面讲的都是从A点运动到B点,而路线都是直线的,一步到位。那假如我们需要它在中途经过C点,就会需要关键点插值函数。给定帧的范围必须要在0-1,也就是把整个运动过程看做1,如果需要在一半的时候插入关键帧,那就是0.5.
在这里插入图片描述
示例如下,在0.5处,即一半路程时插入关键帧。
在这里插入图片描述
请添加图片描述

动画的暂停与恢复

把上面的演示程序改一下,加入暂停和恢复函数。这个功能可以考虑用在agv的停车载货和卸货这个步骤。
在这里插入图片描述
这两个函数其实是他们的父类QAbstactAnimation的成员函数。
在这里插入图片描述
请添加图片描述

动画结束信号

我们希望动画执行结束之后发出一个信号,这个信号可以让我去做其他的事情。实际上QT已经内置了这个信号,接下来看看如何使用?设置信号与槽,用connect函数连接。第一个函数参数是动画对象Anima,第二个是QT规定的结束信号。
在这里插入图片描述
Anima_Finished函数就是我自定义的槽函数,名字可以任意取。
在这里插入图片描述
通过手册可以看到,当动画自然结束时(相对的概念就是强制停止),这个信号会发出。这个动画还有其他几个信号,表示停止、启动、运行中。
在这里插入图片描述
实验:
收到结束信号,就简单显示一个对话框。
在这里插入图片描述
验证成功。
在这里插入图片描述

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐