精华内容
下载资源
问答
  • 动画框架

    2017-06-02 09:28:35
    //动画组 parallelAnimationGroup.addAnimation(animation); parallelAnimationGroup.addAnimation(animation2); } Widget::~Widget() { delete ui; } void Widget::on_pushButton_clicked() { // ...

    widget.h

    
    #include <QWidget>
    #include <QPropertyAnimation>
    #include <QSequentialAnimationGroup>
    #include <QParallelAnimationGroup>
    
    
    namespace Ui {
    class Widget;
    }
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();
    
    private slots:
        void on_pushButton_clicked();
    
    private:
        Ui::Widget *ui;
    
    private:
        QPropertyAnimation *animation;
        QPropertyAnimation *animation2;
        QSequentialAnimationGroup sequentialAnimationGroup;//串行动画组
        QParallelAnimationGroup parallelAnimationGroup;//并行动画组
    };
    

    widget.cpp

    #include "widget.h"
    #include "ui_widget.h"
    
    #include <QStateMachine>
    #include <QSignalTransition>
    #include <QDebug>
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        //常见QPropertyAnimation对象,关联了myWidget这个窗体的几何属性
        animation = new QPropertyAnimation(ui->pushButton, "geometry");
        animation2 = new QPropertyAnimation(ui->pushButton_2, "geometry");
    
        animation->setDuration(1500);//速度,越小越快
        animation->setStartValue(QRect(0,0,120,30));
        animation->setEndValue(QRect(150,150,120,30));
        animation->setEasingCurve(QEasingCurve::Linear);
    //    animation->setEasingCurve(QEasingCurve::OutBounce);//outbounce有一个缓冲的现象
    //    animation->setEasingCurve(QEasingCurve::OutBack);//outback缓慢降落
    //    animation->setEasingCurve(QEasingCurve::OutCirc);//outcirc和outback差不多
    //    animation->setEasingCurve(QEasingCurve::OutInQuart);
    
        animation2->setDuration(1500);
        animation2->setStartValue(QRect(200,0,120,30));
        animation2->setEndValue(QRect(150,180,120,30));
        animation2->setEasingCurve(QEasingCurve::OutBounce);//outbounce有一个缓冲的现象
    
        //动画组
        parallelAnimationGroup.addAnimation(animation);
        parallelAnimationGroup.addAnimation(animation2);
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::on_pushButton_clicked()
    {
    //    animation->start();
    
        parallelAnimationGroup.start();
    }
    
    展开全文
  • Android动画框架详解

    2021-01-31 05:36:59
    Android平台提供了一套完整的动画框架,使得开发者可以用它来开发各种动画效果,本文将向读者阐述 Android的动画框架是如何实现的。任何一个框架都有其优势和局限性,只有明白了其实现原理,开发者才能知道哪些功能...
  • Qt动画框架

    2021-04-28 16:49:27
    Qt动画框架 Qt动画框架是Kinetic项目的一部分,主要目的是提供一种简单的方法用于创建动画的和平滑的GUI。通过Qt动画属性,Qt动画框架为部件和其他QObject对象的动画操作提供了非常大的自由性。Qt动画框架也能...

    Qt动画框架

    Qt动画框架是Kinetic项目的一部分,主要目的是提供一种简单的方法用于创建动画的和平滑的GUI。通过Qt动画属性,Qt动画框架为部件和其他QObject对象的动画操作提供了非常大的自由性。Qt动画框架也能用于图形视图框架中。

    在这片文章中,我们阐述了Qt动画框架的基本结构。我们也提供了一些通用性编码技术方面的例子用于动画操作QObject和图形项。

    Qt动画框架结构

    在这节中,我们宏观了解下Qt动画框架结构以及其怎么被使用于Qt动画属性。下图展示了Qt动画框架中的一些重要类。

     

    Qt动画框架基石由QAbstractAnimation以及它的两个子类QVariantAnimation和QAnimationGroup组成。QAbstractAnimation类是所有动画类的祖先。它包含了一些在框架中被普遍使用的基本功能;尤其是启动、停止和暂停动画功能。它也接收定时触发通知。

    Qt动画框架更是提供了QPropertyAnimation类,该类继承于QVariantAnimation类,用于对Qt属性的动画操作(Qt属性系统是Qt元对象系统的一部分)。QPropertyAnimation类使用缓和曲线算法对属性进行插值演化操作。因此当你想动画改变一个值时,你就声明该值为一个属性值并且使该类为成为一个QObject对象。这给我们提供了很大的方便性去动画操作现有的部件和其他的QObject对象。

    复杂动画可以通过构建QAbstractAnimation树形结构来构造。该树主要使用QAnimationGroup,QAnimationGroup类是一个包含其他动画类的容器类;同时QAnimationGroup类也是QAbstractAnimation类的子类,因此一个容器可以包含其他容器。

    Qt动画框架既是独立的一部分,也是Qt状态机框架的一部分。Qt状态机框架提供一个状态用来行使动画。当QState进入或者退出时可以改变属性,当这个动画状态提供了一个QPropertyAnimatio时,则动画状态即在这些值之间进行插值衍化操作。后续我们将了解的更加仔细。

    在幕后,动画被一个全局定时器控制着,该定时器对所有动画对象发送更新命名。

    为了知道Qt动画框架中各个类的功能角色,请参考相应的类描述信息。

    Qt动画框架类

    这些类提供了框架骨架用于创建简单的和复杂的动画功能

    QAbstractAnimation

    所有动画类的基类

    QAnimationGroup

    动画容器类的抽象基类

    QEasingCurve

    动画控制的缓和曲线类

    QParallelAnimationGroup

    并行动画容器

    QPauseAnimation

    QSequentialAnimationGroup对象暂停延迟

    QPropertyAnimation

    Qt动画属性操作

    QSequentialAnimationGroup

    串行动画容器

    QTimeLine

    动画控制的时间片类

    QVariantAnimation

    动画类的抽象基类

    Qt动画属性

    正如上述所提到的,QPropertyAnimation类能够修改Qt属性值。正是该类用于改变动画属性值;事实上,它的基类QVariantAnimation是一个抽象类,所以QVariantAnimation不能被直接使用。

    我们选用Qt动画属性的一个主要原因是由于它给了我们很大的自由性去动画操作已经存在的类,尤其是拥有bounds、colors等属性的QWidget类(QWidget能被嵌入到QGraphicsView类)。我们看看一个小例子:

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation animation(&button, "geometry");
    animation.setDuration(10000);
    animation.setStartValue(QRect(0, 0, 100, 30));
    animation.setEndValue(QRect(250, 250, 100, 30));
    animation.start();

    上述代码即在10秒的期限把button从屏幕的左上角移动到(250,250)点处。

    上述代码在开始值与结束值之间做了线性插值。当然,设置的值在开始处与结束处之间的数值也是合理的,那么插值衍化就沿这些点进行。

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation animation(&button, "geometry");
    animation.setDuration(10000);
    animation.setKeyValueAt(0, QRect(0, 0, 100, 30));
    animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30));
    animation.setKeyValueAt(1, QRect(0, 0, 100, 30));
    animation.start();

    在这个例子中,在8秒的期限将button移到(250,250),然后在剩下的2秒时间移回至初始的位置;这些点之间的移动都是通过线性插值的。

    你也可以动画操作没有申明动画属性的QObject对象中的值,但是唯一的条件是该值有个能进行修改的设置函数。所以你可以进行子类化,在该类中包含声明属性的值并且有个设置函数。每个Qt属性需要一个获取值的访问函数,因此如果类本身没提供对该值的访问函数的话,你自己就需要提供一个。

    class MyGraphicsRectItem : public QObject, public QGraphicsRectItem
    {
        Q_OBJECT
        Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry)
    };

    如上所示的代码例子中,我们子类化QGraphicsRectItem类并且定义了”geometry”属性。现在我们即可动画操作MyGraphicsRectItem的位置信息了,即使QGraphicsRectItem没有提供”geometry”属性。

    动画和图形视图框架

    当你想动画操作QGraphicsItem时,你也是使用QPropertyAnimation类。然而,QGraphicsItem并不继承于QObject。一个好的解决办法是子类化一个你需要的图形项,同时子类也继承于QObject。使用这种方法,QPropertyAnimation类就能使用于QGraphicsItem中。下面的代码例子展示了这种解决办法。另一种可行性是只继承于QGraphicsWidget,因为QGraphicsWidget继承于QObject。

    class Pixmap : public QObject, public QGraphicsPixmapItem
    {
        Q_OBJECT
        Q_PROPERTY(QPointF pos READ pos WRITE setPos)
        ...
    }

    就如上述所描述的那样,我们定义了一个我们需要动画操作的属性值。

    注意:QObject必须是第一个继承者,因为出于元对象系统的要求。

    缓和曲线

    QPropertyAnimation在开始与结束之间执行插值操作。除了对动画操作设置更多关键值之外,你也可以使用缓和曲线,缓和曲线控制着在0与1之间的插值速度,如果你想在没有改变插值路径的情况下改变动画速度,那么缓和曲线是很有用的。

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation animation(&button, "geometry");
    animation.setDuration(3000);
    animation.setStartValue(QRect(0, 0, 100, 30));
    animation.setEndValue(QRect(250, 250, 100, 30));
    animation.setEasingCurve(QEasingCurve::OutBounce);
    animation.start();

    上述代码中,动画即沿着OutBounce曲线,该曲线样式是到结束处会弹跳起来像个弹跳球。QEasingCurve类有大量的供你选择的曲线,它们被定义成QEasingCurve::Type枚举。如果你需要另外的曲线样式,你也可以自己实现一个,然后用QEasingCurve注册它既可。

    动画分组

    一个应用程序常常包含不止一个动画。例如,你或许希望同时移动不止一个图形项或者一个接着一个的顺序移动它们。

    QAnimationGroup (QSequentialAnimationGroup和QParallelAnimationGroup)的子类是动画容器类,因此多个动画可以被串行或者并行。QAnimationGroup类就是一个例子,其不操作动画属性,但是它能周期性的获得定时通知,这使得它能把定时通知应用于动画中,从而进行控制。

    下面我们来看看使用QSequentialAnimationGroup和QParallelAnimationGroup的例子:

    QPushButton *bonnie = new QPushButton("Bonnie");
    bonnie->show();
    
    QPushButton *clyde = new QPushButton("Clyde");
    clyde->show();
    
    QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry");
    QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry");
    
    QParallelAnimationGroup *group = new QParallelAnimationGroup;
    group->addAnimation(anim1);
    group->addAnimation(anim2);
    group->start();

    并行容器内的动画是同时进行的,调用它的start()函数即开始操作它所管理的所有动画。

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation anim1(&button, "geometry");
    anim1.setDuration(3000);
    anim1.setStartValue(QRect(0, 0, 100, 30));
    anim1.setEndValue(QRect(500, 500, 100, 30));
    
    QPropertyAnimation anim2(&button, "geometry");
    anim2.setDuration(3000);
    anim2.setStartValue(QRect(500, 500, 100, 30));
    anim2.setEndValue(QRect(1000, 500, 100, 30));
    
    QSequentialAnimationGroup group;
    group.addAnimation(&anim1);
    group.addAnimation(&anim2);
    group.start();

    毫无疑问,QSequentialAnimationGroup串行的操作它所管理的动画。

    因为动画容器类也是属于动画,所以你可以把加入到其他动画容器里;用这种方法你就可以建造一个动画树结构,该结构指定了动画之间的相互时间关系。

    动画和状态

    当使用Qt状态机时,我们可以使用QSignalTransition或QEventTransition类将一个或者多个动画与状态之间的切换中进行关联。这些类继承于QAbstractTransition,QAbstractTransition类提供了方便的函数addAnimation(),该函数在状态切换发生的情况下能触发一个或多个被附加的动画。

    我们也可以和状态进行属性关联,而不是自己设置开始和结束值,下面就是一段完整的动画操作QPushButton位置的代码例子:

    QPushButton *button = new QPushButton("Animated Button");
    button->show();
    
    QStateMachine *machine = new QStateMachine;
    
    QState *state1 = new QState(machine);
    state1->assignProperty(button, "geometry", QRect(0, 0, 100, 30));
    
    machine->setInitialState(state1);
    
    QState *state2 = new QState(machine);
    state2->assignProperty(button, "geometry", QRect(250, 250, 100, 30));
    
    QSignalTransition *transition1 = state1->addTransition(button,SIGNAL(clicked()), state2);
    transition1->addAnimation(new QPropertyAnimation(button, "geometry"));
    
    QSignalTransition *transition2 = state2->addTransition(button,SIGNAL(clicked()), state1);
    transition2->addAnimation(new QPropertyAnimation(button, "geometry"));
    
    machine->start();

     

    展开全文
  • 构建canvas动画框架

    2021-03-02 09:14:19
    于是决定自己写一个简单一点的动画框架,以便能更方便地构建出一些动画效果。我将分几个章节来讲述我这个小动画框架的实现:这一节我们先来说说通用类的提取。其实上一篇文章我已经用到了这种从flash借鉴来的思路:...
  • 自定义动画框架

    2017-10-05 19:38:54
    安卓动画框架,http://blog.csdn.net/qq_18983205/article/details/78157447对应代码
  • iOS的动画框架

    2021-04-05 15:07:23
    作者IFTTT,源码RazzleDazzle,编写的一个简单keyframe-based iOS的动画框架,迅速。适合滚动应用的介绍。
  • 非常简单的动画框架

    2021-04-04 02:31:41
    源码FastAnimationWithPOP,FastAnimation是一个非常简单的动画框架,不用增加代码就可以添加动画效果。使用了Facebook 的动画引擎框架POP。功能:使用属性给视图添加动画效果以及为控件绑定动画;可从NIB文件自动...
  • Qt动画框架Qt动画框架动画架构动画框架中的类动画Qt属性动画和图形视图框架缓和曲线将动画放在一起 Qt动画框架 动画框架旨在为创建动画和平滑的GUI提供一种简便的方法。通过对Qt属性进行动画处理,框架为动画小部件...

    Qt动画框架

    动画框架旨在为创建动画和平滑的GUI提供一种简便的方法。通过对Qt属性进行动画处理,框架为动画小部件和其他QObject提供了极大的自由度。该框架也可以与Graphics View框架一起使用。Qt Quick中还提供了动画框架中可用的许多概念,其中提供了定义动画的声明性方法。

    在本概述中,我们解释了其体系结构的基础。我们还展示了该框架允许对QObject和图形项进行动画处理的最常见技术的示例。

    动画架构

    在本节中,我们将对动画框架的体系结构以及如何将其用于Qt属性进行动画化进行高层次的研究。下图显示了动画框架中最重要的类。
    在这里插入图片描述
    动画框架的基础包括基类QAbstractAnimation及其两个子类QVariantAnimation和QAnimationGroup。QAbstractAnimation是所有动画的始祖。它表示框架中所有动画共有的基本属性。值得注意的是,具有启动,停止和暂停动画的能力。它还接收时间更改通知。

    动画框架还提供了QPropertyAnimation类,该类继承了QVariantAnimation并执行Qt属性的动画,该属性是Qt元对象系统的一部分。该类使用缓动曲线对属性执行插值。因此,当您要为一个值设置动画时,可以将其声明为属性,并使您的类成为QObject。注意,这给我们提供了极大的自由,可以为已经存在的小部件和其他QObject设置动画。

    可以通过构建QAbstractAnimation的树结构来构造复杂的动画。通过使用QAnimationGroup来构建树,QAnimationGroup用作其他动画的容器。还要注意,组是QAbstractAnimation的子类,因此组本身可以包含其他组。

    在幕后,动画由全局计时器控制,该计时器将更新发送到所有正在播放的动画。

    动画框架中的类

    这些类提供了用于创建简单和复杂动画的框架。

    QAbstractAnimation

    所有动画的基础

    QAnimationGroup

    动画组的抽象基类

    QEasingCurve

    缓和曲线以控制动画

    QParallelAnimationGroup

    平行动画组

    QPauseAnimation

    暂停QSequentialAnimationGroup

    QPropertyAnimation

    动画Qt属性

    QSequentialAnimationGroup

    顺序动画组

    QTimeLine

    控制动画的时间线

    QVariantAnimation

    动画基础类

    动画Qt属性

    如上一节所述,QPropertyAnimation类可以在Qt属性上进行插值。通常应该使用此类来进行值的动画处理。实际上,它的超类QVariantAnimation具有updateCurrentValue()的空实现,并且除非我们在valueChanged信号上自行对其进行更改,否则不会更改任何值。

    我们选择对Qt属性进行动画处理的主要原因是,它使我们可以自由地对Qt API中已经存在的类进行动画处理。值得注意的是,QWidget类(我们也可以将其嵌入QGraphicsView中)具有其边界,颜色等属性。让我们看一个小例子:

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation animation(&button, "geometry");
    animation.setDuration(10000);
    animation.setStartValue(QRect(0, 0, 100, 30));
    animation.setEndValue(QRect(250, 250, 100, 30));
    
    animation.start();
    

    此代码将button在10秒(10000毫秒)内从屏幕的左上角移至位置(250,250)。

    上面的示例将在开始值和结束值之间进行线性插值。也可以设置介于开始值和结束值之间的值。插值将按照这些点进行。

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation animation(&button, "geometry");
    animation.setDuration(10000);
    
    animation.setKeyValueAt(0, QRect(0, 0, 100, 30));
    animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30));
    animation.setKeyValueAt(1, QRect(0, 0, 100, 30));
    
    animation.start();
    

    在此示例中,动画将在8秒钟内将按钮移至(250,250),然后在剩下的2秒钟内将其移回到其原始位置。运动将在这些点之间线性插值。

    您还可以对未声明为Qt属性的QObject的值进行动画处理。唯一的要求是该值有一个setter。然后,您可以对包含该值的类进行子类化,并声明使用此setter的属性。请注意,每个Qt属性都需要一个吸气剂,因此,如果未定义,则需要自己提供一个吸气剂。

    class MyGraphicsRectItem : public QObject, public QGraphicsRectItem
    {
        Q_OBJECT
        Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry)
    };
    

    在上面的代码示例中,我们将QGraphicsRectItem子类化,并定义了geometry属性。现在,即使QGraphicsRectItem不提供geometry属性,我们也可以对小部件的几何图形进行动画处理。

    动画和图形视图框架

    要为QGraphicsItem设置动画时,还可以使用QPropertyAnimation。但是,QGraphicsItem不继承QObject。一个好的解决方案是将您要设置动画的图形项目子类化。然后,此类还将继承QObject。这样,QPropertyAnimation可以用于QGraphicsItem。下面的示例显示了此操作的完成方式。另一种可能性是继承QGraphicsWidget,它已经是QObject了。

    class Pixmap : public QObject, public QGraphicsPixmapItem
    {
        Q_OBJECT
        Q_PROPERTY(QPointF pos READ pos WRITE setPos)
        ...
    

    如前一节所述,我们需要定义希望设置动画的属性。

    请注意,因为元对象系统需要这样做,所以QObject必须是继承的第一类。

    缓和曲线

    如前所述,QPropertyAnimation在开始和结束属性值之间执行插值。除了向动画添加更多关键值外,您还可以使用缓和曲线。缓和曲线描述了一个控制0和1之间插值速度应如何的功能,如果要在不更改插值路径的情况下控制动画的速度,该曲线将很有用。

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation animation(&button, "geometry");
    animation.setDuration(3000);
    animation.setStartValue(QRect(0, 0, 100, 30));
    animation.setEndValue(QRect(250, 250, 100, 30));
    
    animation.setEasingCurve(QEasingCurve::OutBounce);
    
    animation.start();
    

    在这里,动画将遵循一条曲线,使其像球一样反弹,就像从起点到终点的位置一样。QEasingCurve有大量曲线供您选择。这些由QEasingCurve :: Type枚举定义。如果您需要另一条曲线,也可以自己实现,然后向QEasingCurve注册。

    将动画放在一起

    一个应用程序通常包含多个动画。例如,您可能想同时移动多个图形项目,或者依次移动它们。

    QAnimationGroup的子类(QSequentialAnimationGroup和QParallelAnimationGroup)是其他动画的容器,因此可以按顺序或并行对这些动画进行动画处理。该QAnimationGroup是不动画属性动画的例子,但它得到定期通知的时间变化。这使它可以将这些时间更改转发到其所包含的动画,从而控制何时播放其动画。

    让我们看一下同时使用QSequentialAnimationGroup和QParallelAnimationGroup的代码示例,从后者开始。

    QPushButton *bonnie = new QPushButton("Bonnie");
    bonnie->show();
    
    QPushButton *clyde = new QPushButton("Clyde");
    clyde->show();
    
    QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry");
    // Set up anim1
    
    QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry");
    // Set up anim2
    
    QParallelAnimationGroup *group = new QParallelAnimationGroup;
    group->addAnimation(anim1);
    group->addAnimation(anim2);
    
    group->start();
    

    一个并行组可以同时播放多个动画。调用其start()函数将启动其控制的所有动画。

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation anim1(&button, "geometry");
    anim1.setDuration(3000);
    anim1.setStartValue(QRect(0, 0, 100, 30));
    anim1.setEndValue(QRect(500, 500, 100, 30));
    
    QPropertyAnimation anim2(&button, "geometry");
    anim2.setDuration(3000);
    anim2.setStartValue(QRect(500, 500, 100, 30));
    anim2.setEndValue(QRect(1000, 500, 100, 30));
    
    QSequentialAnimationGroup group;
    
    group.addAnimation(&anim1);
    group.addAnimation(&anim2);
    
    group.start(
    

    毫无疑问,QSequentialAnimationGroup按顺序播放其动画。前一个动画结束后,它将开始列表中的下一个动画。

    由于动画组本身就是动画,因此可以将其添加到另一个组中。这样,您可以构建动画的树结构,该树结构指定动画相对于彼此的播放时间。

    展开全文
  • 基于rebound的动画框架

    2021-04-04 20:14:10
    源码Backboard,Backboard是一个基于rebound的动画框架。Backboard是一个基于rebound 的框架,它管理spring的使用,简化了最常用的用例。
  • Qt 之动画框架

    万次阅读 多人点赞 2016-07-07 15:14:09
    简述Qt动画框架旨在为创建动画和平滑的GUI提供了一种简单的方法。通过Qt动画属性,该框架为部件和其它QObject对象的动画操作提供了非常大的自由性,框架也可以被用于图形视图框架中,动画框架中许多可用的概念也可以...

    简述

    Qt动画框架旨在为创建动画和平滑的GUI提供了一种简单的方法。通过Qt动画属性,该框架为部件和其它QObject对象的动画操作提供了非常大的自由性,框架也可以被用于图形视图框架中,动画框架中许多可用的概念也可以用于Qt Quick,它提供了一种声明式的方式定义动画。大部分关于动画框架学到的知识都可以应用于Qt Quick。

    本篇,我们阐述了Qt动画框架的基本结构。同时,会展示最常见的技术示例,用于动画操作QObject和图形项。

    | 版权声明:一去、二三里,未经博主允许不得转载。

    动画框架结构

    本节中,我们将宏观了解Qt动画框架的体系结构,以及如何被用于Qt动画属性。下图展示了动画框架中最重要的类。

    这里写图片描述

    动画框架基础由基类QAbstractAnimation以及它的两个子类QVariantAnimation、QAnimationGroup组成。QAbstractAnimation是所有动画的祖先。它包含了一些在框架中被普遍使用的基本功能,尤其是启动、停止和暂停动画功能,它也接收定时触发通知。

    Qt动画框架更是提供了QPropertyAnimation类,该类继承自QVariantAnimation,用于对Qt属性的动画操作(Qt属性系统是Qt元对象系统的一部分)。QPropertyAnimation类使用缓和曲线算法对属性进行插值演化操作。因此当你想使用动画改变一个值时,需要声明其为一个属性并且使该类继承自QObject。这给我们提供了很大的方便性,去动画操作现有的部件和其它的QObject对象。

    复杂动画可以通过构建QAbstractAnimation树形结构来构造。该树主要使用QAnimationGroup,QAnimationGroup类是一个包含其它动画类的容器类;同时QAnimationGroup类也是QAbstractAnimation类的子类,因此一个容器可以包含其它容器。

    Qt动画框架可以独立使用,但是也被设计为Qt状态机框架的一部分。状态机框架提供一个特殊的状态用来播放动画。当状态进入或者退出时,QState也可以改变属性。当这个动画状态提供了一个QPropertyAnimatio时,这个特殊的状态会在这些值之间进行篡改操作。后续我们将了解的更加仔细。

    在幕后,动画被一个全局定时器控制着,该定时器对所有正在运行的动画发送更新命令。

    要了解Qt动画框架中各个类的功能,请参考相应的类描述信息。

    动画框架类

    这些类提供了用于创建简单的和复杂的动画的框架

    描述
    QAbstractAnimation 所有动画类的基类
    QAnimationGroup 动画容器类的抽象基类
    QEasingCurve 动画控制的缓和曲线类
    QParallelAnimationGroup 并行动画容器
    QPauseAnimation QSequentialAnimationGroup暂停
    QPropertyAnimation Qt的动画属性
    QSequentialAnimationGroup 串行动画容器
    QTimeLine 控制动画的时间轴类
    QVariantAnimation 动画类的抽象基类

    Qt动画属性

    如上所述,QPropertyAnimation类能够修改Qt属性值,正是该类用于改变动画属性值。事实上,它的基类QVariantAnimation是一个抽象类,所以不能被直接使用。

    选用Qt动画属性的一个主要原因,是因为它给我们很大的自由性去动画操作Qt API中已经存在的类,尤其是拥有bounds、colors等属性的QWidget类(能被嵌入到QGraphicsView中的QWidget)。

    来看一个小例子:

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation animation(&button, "geometry");
    animation.setDuration(10000);
    animation.setStartValue(QRect(0, 0, 100, 30));
    animation.setEndValue(QRect(250, 250, 100, 30));
    
    animation.start();

    上述代码,在10秒的持续时间把button从屏幕的左上角移动到(250, 250)点处。

    上面的例子在开始值与结束值之间做了线性插值。当然,设置的值在开始处与结束处之间的数值也是合理的,那么插值衍化就沿这些点进行。

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation animation(&button, "geometry");
    animation.setDuration(10000);
    
    animation.setKeyValueAt(0, QRect(0, 0, 100, 30));
    animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30));
    animation.setKeyValueAt(1, QRect(0, 0, 100, 30));
    
    animation.start();

    这个例子中,在8秒的持续时间将button移到(250, 250),然后在剩下的2秒再移回至初始位置;这些点之间的移动都是通过线性插值的。

    你也可以动画操作没有声明动画属性的QObject对象中的值,但是唯一的条件是该值有个能进行修改的设置函数。所以可以进行子类化,在该类中包含声明属性的值并且有个设置函数。每个Qt属性需要一个获取值的访问函数,因此如果类本身没提供对该值的访问函数的话,你自己就需要提供一个。

    class MyGraphicsRectItem : public QObject, public QGraphicsRectItem
    {
        Q_OBJECT
        Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry)
    };

    如上所示的代码例子中,我们子类化QGraphicsRectItem类,并且定义了”geometry”属性。即使QGraphicsRectItem没有提供”geometry”属性,我们也可以动画操作MyGraphicsRectItem的位置信息了。

    动画和图形视图框架

    当你想动画操作QGraphicsItem时,也可以使用QPropertyAnimation类。然而,QGraphicsItem并不继承于QObject。一个好的解决办法是子类化一个你需要的图形项,同时这个类也继承自QObject。通过这种方式,QPropertyAnimation类就能适用于QGraphicsItem。下面的代码例子展示了这是如何实现的。另一种可行性是只继承于QGraphicsWidget,因为QGraphicsWidget继承于QObject。

    class Pixmap : public QObject, public QGraphicsPixmapItem
    {
        Q_OBJECT
        Q_PROPERTY(QPointF pos READ pos WRITE setPos)
        ...

    如上所述,我们定义了一个需要动画操作的属性值。

    注意:出于元对象系统的要求,QObject必须是第一个继承者。

    缓和曲线

    QPropertyAnimation在开始与结束之间执行插值操作。除了为动画添加更多的键值外,你也可以使用缓和曲线,缓和曲线控制着在0与1之间的插值速度,如果你想在没有改变插值路径的情况下改变动画速度,那么缓和曲线是很有用的。

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation animation(&button, "geometry");
    animation.setDuration(3000);
    animation.setStartValue(QRect(0, 0, 100, 30));
    animation.setEndValue(QRect(250, 250, 100, 30));
    
    animation.setEasingCurve(QEasingCurve::OutBounce);
    
    animation.start();

    这里,动画即沿着OutBounce曲线,该曲线样式是到结束处会弹跳起来像个弹跳球。QEasingCurve类有大量供选择的曲线,它们被定义成QEasingCurve::Type枚举。如果你需要另外的曲线样式,也可以自己实现一个,然后用QEasingCurve注册它既可。

    动画分组

    一个应用程序常常包含多个动画。例如,你或许希望同时移动不止一个图形项或者一个接一个的顺序移动它们。

    QAnimationGroup(QSequentialAnimationGroup和QParallelAnimationGroup)的子类是动画容器类,因此多个动画可以被串行或者并行执行。QAnimationGroup类就是一个例子,其不操作动画属性,但是它能周期性的获得定时通知,这使得它能把定时通知应用于动画中,从而进行控制。

    下面我们来看看使用QSequentialAnimationGroup和QParallelAnimationGroup的例子:

    QPushButton *bonnie = new QPushButton("Bonnie");
    bonnie->show();
    
    QPushButton *clyde = new QPushButton("Clyde");
    clyde->show();
    
    // 动画一
    QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry");
    
    // 动画二
    QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry");
    
    QParallelAnimationGroup *group = new QParallelAnimationGroup;
    group->addAnimation(anim1);
    group->addAnimation(anim2);
    
    group->start();

    并行容器内的动画是同时进行的,调用它的start()函数即开始操作它所管理的所有动画。

    QPushButton button("Animated Button");
    button.show();
    
    QPropertyAnimation anim1(&button, "geometry");
    anim1.setDuration(3000);
    anim1.setStartValue(QRect(0, 0, 100, 30));
    anim1.setEndValue(QRect(500, 500, 100, 30));
    
    QPropertyAnimation anim2(&button, "geometry");
    anim2.setDuration(3000);
    anim2.setStartValue(QRect(500, 500, 100, 30));
    anim2.setEndValue(QRect(1000, 500, 100, 30));
    
    QSequentialAnimationGroup group;
    
    group.addAnimation(&anim1);
    group.addAnimation(&anim2);
    
    group.start();

    毫无疑问你已经猜到了,QSequentialAnimationGroup串行的操作它所管理的动画。

    因为动画容器类也是动画,所以你可以将其加入到其它动画容器里;用这种方式,就可以建造一个动画树结构,该结构指定了动画彼此之间运行的关系。

    动画和状态

    当使用状态机时,我们可以使用QSignalTransition或QEventTransition类将一个或者多个动画与状态之间的切换中进行关联。这些类继承于QAbstractTransition,QAbstractTransition类提供了便利的函数addAnimation(),该函数在状态切换发生的情况下能触发一个或多个被附加的动画。

    我们也可以和状态进行属性关联,而不是自己设置开始和结束值,下面就是一段完整的动画操作QPushButton位置的代码例子:

    QPushButton *button = new QPushButton("Animated Button");
    button->show();
    
    QStateMachine *machine = new QStateMachine;
    
    QState *state1 = new QState(machine);
    state1->assignProperty(button, "geometry", QRect(0, 0, 100, 30));
    machine->setInitialState(state1);
    
    QState *state2 = new QState(machine);
    state2->assignProperty(button, "geometry", QRect(250, 250, 100, 30));
    
    QSignalTransition *transition1 = state1->addTransition(button,
        SIGNAL(clicked()), state2);
    transition1->addAnimation(new QPropertyAnimation(button, "geometry"));
    
    QSignalTransition *transition2 = state2->addTransition(button,
        SIGNAL(clicked()), state1);
    transition2->addAnimation(new QPropertyAnimation(button, "geometry"));
    
    machine->start();

    有关如何使用动画状态机框架更全面的示例,请参见状态示例(位于examples/animation/states目录)。

    更多参考

    展开全文
  • QT 动画框架

    2018-04-19 17:26:17
    QT动画框架 其目的是提供一种简单的方法来创建平滑的具有动画效果的GUI界面.该框架是通过控制Qt的属性来实现动画的,可以应用在窗口部件和其他QObject对象上,也可以应用在图形视图框架中. 基类为QAbstractAnimation...
  • QT学习之动画框架

    千次阅读 2019-01-23 16:28:32
    文章目录动画框架使用属性动画使用缓和曲线动画组在图形视图框架中使用动画 动画框架 使用属性动画 使用缓和曲线 动画组 在一个应用中经常包含多个动画,要同时移动多个图形项或者让他们一个接一个串行移动 在...
  • html5动画框架collie

    2016-08-04 20:45:33
    html5动画框架collie
  • Qt 动画框架

    千次阅读 2014-02-10 13:43:09
    Qt动画框架由本人终于翻译完毕,这里的每个字母、每个汉字、每张图片都是有本人一个一个敲打出来的,现把它共享出来。  Qt动画框架是Kinetic项目的一部分,主要目的是提供一种简单的方法用于创建动画的和平滑...
  • Android 动画框架

    千次阅读 2018-10-26 17:53:18
    1.炫酷开屏动画框架 githubhttps://github.com/JoshuaRogue/FancyView 2.Animate 一个教你基础动画实现的dome githubhttps://github.com/hitherejoe/animate 3.awesome-animation 一个不定期更新各类Android ....
  • Android 动画框架NineOldAndroids,里面有一个lib和一个演示demo
  • gsap是目前非常流行的前端动画框架,可以非常轻松构造出复杂的动画效果,这里仅对我实际使用中的一些例子进行总结 官网 示例 文章种所使用代码的在线示例 基础用法 // 声明一个滚动控制器 let ctrl = new ...
  • 一、动画框架概要 Qt动画框架的目的是提供一种简单的方法来创建具有动画效果的GUI界面(图形用户界面,是指采用图形方式显示的计算机操作用户)。该框架是通过控制Qt的属性来实现动画的。是由QAbstractAnimation...
  • 作者HZQuan,源码Bzier-Animation-FloatingWindow,悬浮窗圆形转场动画框架,首先是实现了悬浮窗,然后再添加了圆形缩小的入场动画和圆形扩大的出场动画,可以给所有的controller添加这个效果。
  • 直播动画框架探索

    2020-11-27 11:44:14
    直播动画框架探索 方案选择 直播动画框架探索 方案对比 方案 优点 缺点 帧动画OpenGL 实现简单 播放图片资源占用高; 属性动画 资源占用小 1. 播放图片资源占用高; 2. 实现难度...
  • 自定义转场动画框架
  • AllAnimation.css是一款带37种3D动画特效的跨浏览器CSS3动画框架。它可以轻松的制作出各种CSS3 3D动画效果,可以在移动手机上使用。并且使用极其简单,使用时只需要添加相应的class即可。
  • iOS 和 OS X 动画框架 Pop ,Pop 是 Facebook 推出的一个可扩展的 iOS 和 OS X 动画框架。Facebook的...
  • android 动画框架

    2017-05-15 11:08:50
    lottie 动画框架 https://github.com/airbnb/lottie-android com.airbnb.lottie.LottieAnimationView android:id="@+id/animation_view" android:layout_width="wrap_content" android:layo

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,739
精华内容 3,895
关键字:

动画框架