【QT进阶】第十三章QT动画类的使用QAbstractAnimation

时间:2024-10-30 08:30:13

❤️作者主页:凉开水白菜
❤️作者简介:共同学习,互相监督,热于分享,多加讨论,一起进步!
❤️专栏目录:【零基础学QT】文章导航篇
❤️专栏资料:/s/192A28BTIYFHmixRcQwmaHw 提取码:qtqt
❤️点赞 ???? 收藏 ⭐再看,养成习惯

订阅的粉丝可通过PC端文末加我微信,可对文章的内容进行一对一答疑!


文章目录

  • 一、简介
  • 二、动画类
    • 2.1 平移
    • 2.2 缩放
    • 2.3 循环动画
    • 2.4 渐隐渐显
    • 2.5 动画曲线
  • 三、信号与槽
    • 3.1 动画结束信号
    • 3.2 动画循环次数信号
  • 四、串行、并行、延时动画
    • 4.1 串行动画
    • 4.2 并行动画
    • 4.3 延时动画
  • 最后


一、简介

QPropertyAnimation 是 Qt 自带的动画类,该类可以实现简单的控件动画效果,比如对控件的移动、缩放、不透明度这些来做动画效果,下面通过几个例子来熟悉给控件添加动画。

二、动画类

在这里插入图片描述
从帮助手册可以看到动画类的基类是QAbstractAnimation,包含在core这个模块中,其中基类又衍生出很多动画类他们的构成如下

类名 功能介绍
QAbstractAnimation 动画基类 提供基本的动画属性和接口,它有两个子类 QVariantAnimation 和 QAnimationGroup。QAbstractAnimation 是其他所有类的父类。它提供了基础的属性,适用于所有的本框架下的动画。
QAbstractAnimation 是其他所有类的父类 实现了一个 Qt 动画属性,比如对控件的大小缩放、位置移动、透明度变化的动画效果实现。修改的属性一定是类具有的属性,类中要有属性定义 Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry),否则要声明属性,并实践READ和WRITE方法。
QParallelAnimationGroup 并行动画类 将多个属性动画 QPropertyAnimation 添加到一个 QParallelAnimationGroup,实现并行执行动画。
QSequentialAnimationGroup 串行动画类 QSequentialAnimationGroup,将多个 QPropertyAnimation 串联在一起实现,按照添加顺序先后执行动画。
QPauseAnimation 停顿类 在串行动画中,添加一个暂停的动画,可以实现延时效果。
QEasingCurve速度 曲线类 Qt动画运动的速度曲线,枚举了 45 种,详见下文

2.1 平移

在这里插入图片描述

QPropertyAnimation *pAnimation = new QPropertyAnimation(ui->label, "pos");
    pAnimation->setDuration(1000);                  // 设置动画执行时间,单位毫秒
    pAnimation->setStartValue(QPoint(200, 10));     // 初始值
    pAnimation->setEndValue(QPoint(200, 300));      // 结束值
    pAnimation->start();												// 开始动画
  • 1
  • 2
  • 3
  • 4
  • 5

setDuration设置执行这段动画的时间
setStartValue表示设置控件的开始这个动画的位置
setEndValue表示设置控制动画结束出现的位置
start开始这段动画需要调用开始

2.2 缩放

在这里插入图片描述

QPropertyAnimation *pAnimation = new QPropertyAnimation(ui->label, "geometry");
    pAnimation->setDuration(1000);                          // 设置动画执行时间,单位毫秒
    pAnimation->setStartValue(QRect(100, 100, 200, 200));   // 初始值
    pAnimation->setEndValue(QRect(200, 100,100, 100));      // 结束值
//    pAnimation->start(QAbstractAnimation::DeleteWhenStopped); // 执行动画,结束后删除对象
    pAnimation->start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

setStartValue这里函数传入的是qrect相当于两个信息,一个是位置坐标,一个是控件尺寸

2.3 循环动画

在这里插入图片描述

QPropertyAnimation *pAnimation = new QPropertyAnimation(ui->label, "pos");
pAnimation->setDuration(1000);                  // 设置动画执行时间,单位毫秒
pAnimation->setStartValue(QPoint(200, 10));     // 初始值
pAnimation->setEndValue(QPoint(200, 300));      // 结束值
pAnimation->setLoopCount(10);
pAnimation->start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

setLoopCount设置的是该动画播放的次数

2.4 渐隐渐显

在这里插入图片描述

QGraphicsOpacityEffect *pLabelOpacity = new QGraphicsOpacityEffect(this);
pLabelOpacity->setOpacity(1);
ui->label->setGraphicsEffect(pLabelOpacity);

QPropertyAnimation *pOpacityAnimation1 = new QPropertyAnimation(pLabelOpacity, "opacity");
pOpacityAnimation1->setDuration(1000);
pOpacityAnimation1->setStartValue(0);
pOpacityAnimation1->setEndValue(1);

// pAnimation–>setDirection(QAbstractAnimation::Backward); // 反向动画显示

pOpacityAnimation1->start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

因为 Qt 控件没有透明度属性opacity,所以需要通过 QGraphicsOpacityEffect 实现控件绘图效果实现透明度改变,setOpacity从0到1就可以实现从不显示到显示;
setDirection可以实现动画的显示方向,用在这里可以做较好的看到效果,从不显示到显示反向过来就是从显示到消失;

2.5 动画曲线

动画还可以设置时间的插值曲线,默认是linear,即线性运动,通过设置 QEasingCurve 即可。Qt 提供了 40 种已经定义好的曲线(如果有需要也可以自定义曲线):
在这里插入图片描述

QPropertyAnimation *pAnimation = new QPropertyAnimation(ui->label, "geometry");
    pAnimation->setDuration(1000);                          // 设置动画执行时间,单位毫秒
    pAnimation->setStartValue(QRect(100, 100, 200, 200));   // 初始值
    pAnimation->setEndValue(QRect(200, 100,100, 100));      // 结束值
    pAnimation->setEasingCurve(QEasingCurve::InOutCirc);    // 设置速度曲线
//    pAnimation->start(QAbstractAnimation::DeleteWhenStopped); // 执行动画,结束后删除对象
    pAnimation->start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

enum Type {
        Linear,
        InQuad, OutQuad, InOutQuad, OutInQuad,
        InCubic, OutCubic, InOutCubic, OutInCubic,
        InQuart, OutQuart, InOutQuart, OutInQuart,
        InQuint, OutQuint, InOutQuint, OutInQuint,
        InSine, OutSine, InOutSine, OutInSine,
        InExpo, OutExpo, InOutExpo, OutInExpo,
        InCirc, OutCirc, InOutCirc, OutInCirc,
        InElastic, OutElastic, InOutElastic, OutInElastic,
        InBack, OutBack, InOutBack, OutInBack,
        InBounce, OutBounce, InOutBounce, OutInBounce,
        InCurve, OutCurve, SineCurve, CosineCurve,
        BezierSpline, TCBSpline, Custom, NCurveTypes
    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

三、信号与槽

3.1 动画结束信号

QPropertyAnimation *pAnimation = new QPropertyAnimation(ui->label, "pos");
    pAnimation->setDuration(1000);                  // 设置动画执行时间,单位毫秒
    pAnimation->setStartValue(QPoint(200, 10));     // 初始值
    pAnimation->setEndValue(QPoint(200, 300));      // 结束值
    pAnimation->start();

    connect(pAnimation, &QAbstractAnimation::finished, [=]() {
        QMessageBox::information(this, tr("提示"),
                                       tr("动画执行完成提示"),
                                       QMessageBox::Ok);
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

当动画结束后动画类会发出一个finished信号,我们可以在该槽函数中进行页面的切换或则下一个动画的开始等等操作

3.2 动画循环次数信号

QPropertyAnimation *pAnimation = new QPropertyAnimation(ui->label, "pos");
    pAnimation->setDuration(1000);                  // 设置动画执行时间,单位毫秒
    pAnimation->setStartValue(QPoint(200, 10));     // 初始值
    pAnimation->setEndValue(QPoint(200, 300));      // 结束值
    pAnimation->setLoopCount(5);
    pAnimation->start();


    connect(pAnimation, &QAbstractAnimation::currentLoopChanged, [=](int cur_num) {
        if(cur_num == 3)
        QMessageBox::information(this, tr("提示"),
                                 tr("动画执行快结束了"),
                                 QMessageBox::Ok);
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在循环动画中每次执行完一次动画会产生的一个信号,我们可以在槽函数做对动画进行改变实现不同的效果;

四、串行、并行、延时动画

要理解这个首先需要理解什么是串行什么是并行,串行动画就是在几个动画执行中依次执行,例如我点击渐隐动画后点击渐显动画就是在隐藏动画结束后再执行显示这就是串行执行,并行动画就是几个动画同时一起执行,例如上方的例子中在循环动画的时候我可以点击渐隐动画就可以实现移动消失的效果,这就是并行执行,当然这些效果也可以通过代码来实现;

4.1 串行动画

在这里插入图片描述

QPropertyAnimation *pAnimation1 = new QPropertyAnimation(ui->label, "pos");
pAnimation1->setDuration(1000);                  // 设置动画执行时间,单位毫秒
pAnimation1->setStartValue(QPoint(200, 10));     // 初始值
pAnimation1->setEndValue(QPoint(200, 300));      // 结束值

QPropertyAnimation *pAnimation2 = new QPropertyAnimation(ui->label, "pos");
pAnimation2->setDuration(1000);                  // 设置动画执行时间,单位毫秒
pAnimation2->setStartValue(QPoint(200, 300));     // 初始值
pAnimation2->setEndValue(QPoint(500, 300));      // 结束值

QSequentialAnimationGroup *m_group = new QSequentialAnimationGroup(this);
m_group->addAnimation(pAnimation1);
m_group->addAnimation(pAnimation2);

m_group->start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

创建两个动画一个是下移一个是左移,可以看到串行是先执行完下移再进行左移;

4.2 并行动画

在这里插入图片描述

QPropertyAnimation *pAnimation = new QPropertyAnimation(ui->label, "pos");
pAnimation->setDuration(1000);                  // 设置动画执行时间,单位毫秒
pAnimation->setStartValue(QPoint(200, 10));     // 初始值
pAnimation->setEndValue(QPoint(200, 300));      // 结束值

QGraphicsOpacityEffect *pLabelOpacity = new QGraphicsOpacityEffect(this);
pLabelOpacity->setOpacity(1);
ui->label->setGraphicsEffect(pLabelOpacity);

QPropertyAnimation *pOpacityAnimation1 = new QPropertyAnimation(pLabelOpacity, "opacity");
pOpacityAnimation1->setDuration(1000);
pOpacityAnimation1->setStartValue(0);
pOpacityAnimation1->setEndValue(1);

QParallelAnimationGroup *m_group = new QParallelAnimationGroup(this);
m_group->addAnimation(pAnimation);
m_group->addAnimation(pOpacityAnimation1);

m_group->start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

创建两个动画一个是下移一个是渐显,可以看到并行任务就是同时执行下移动的过程中显示出控制;

4.3 延时动画

在这里插入图片描述

QPropertyAnimation *pAnimation = new QPropertyAnimation(ui->label, "pos");
pAnimation->setDuration(1000);                  // 设置动画执行时间,单位毫秒
pAnimation->setStartValue(QPoint(200, 10));     // 初始值
pAnimation->setEndValue(QPoint(200, 300));      // 结束值


QSequentialAnimationGroup *m_group = new QSequentialAnimationGroup(this);
m_group->addPause(500);
m_group->addAnimation(pAnimation);

m_group->start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

延时动画的实现比较简单在串行动画中添加一个延时动画类就行了

最后

动画类的扩展性比较强,对动画比较有研究的同学可以通过上面几个简单的组合实现优美的动画,各个Group的组合也可以组合成不同的效果,期待大家的作品;

完整的代码工程我都放在百度云盘的软件里面,如果需要可以自行下载;

❤️专栏资料:/s/192A28BTIYFHmixRcQwmaHw 提取码:qtqt


我是凉开水白菜,我们下文见~