zoukankan      html  css  js  c++  java
  • Qt动画框架The Animation Framework

    动画框架是Kinetic(运动)项目的一部分,它的目标是提供一中简单的方法创建动画的和流畅的GUI。借助Qt动画属性,可以提供非常自由的动画窗体组件和其他对象(QObjects)。动画框架也能被用于图形视图框架。
            一下概述解释动画框架体系结构的基础部分。示例展示了QObject和图形项(graphics items)显示动画中使用的绝大多数基本动画技术。

    The Animation Architecture
    Classes in the Animation Framework
    Animating Qt Properties
    Animations and the Graphics View Framework
    Easing Curves
    Putting Animations Together
    Animations and States
    动画体系结构
              本部分从较高层次介绍动画框架的结构和对Qt动画属性的使用。下图显示了动画框架中大部分重要的类。


    动画框架的基础由基类QAbstractAnimation组成,它有两个子类QVariantAnimation 和QAnimationGroup。QAbstractAnimation是其他所有类的父类。它提供了基础的属性,适用于所有的本框架下的动画;notably、开始能力、停止、中止一个动画。它也接受时间改变notifications。
    此外动画框架提供了 QPropertyAnimation类,它继承自QVariantAnimation,实现了一个Qt动画属性。它是Qt的meta-object system的一部分。QPropertyAnimation通过属性使用一个释放曲线(easing curve)执行一个槽。所以当你想让某一个值动起来,你可以声明这个值作为一个属性,并且创建一个QObject类。
    可以构建一个QAbstractAnimations树来表现复杂的动画。树由QAnimationGroup来实现,它的功能是作为其他动画的容器。QAnimationGroup(组)可以是QAbstractAnimation的子类,所有组可以包含其他的组。


    动画框架中的类
    这些类提供了创建简单和复杂动画的框架。
    QAbstractAnimation 其他动画类的基类
    QAnimationGroup Abstract base class for groups of animations
    QEasingCurve 控制动画释放的曲线
    QParallelAnimationGroup 并行动画组
    QPauseAnimation 中止一个串行组
    QPropertyAnimation Qt的动画属性
    QSequentialAnimationGroup 串行动画组
    QTimeLine 控制动画的时间线
    QVariantAnimation Abstract base class for animations
    Qt动画属性
    前边提到的QPropertyAnimation类能添加新的Qt属性。前提是它被这个类用作董哈的属性值。实际上,它的父类QVariantAnimation是一个抽象类,不能被直接使用。
    选择动画Qt属性的一个主要原因是使我们能容易的使用已经存在的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();

    这段代码把一个按钮在2秒内从屏幕的左上角移动到(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属性,需提供访问方法
    class MyGraphicsItem : public QObject, public QGraphicsRectItem
    {
               Q_OBJECT
               Q_PROPERTY(QRectF geometry READ geometry setGeometry)
    }
    上边示例中,我们子类化QGraphicsRectItem并且定义geometry属性。即使QGraphicsRectItem没有geometry属性,我们也可以使用本组件的geometry属性进行动画。

    动画和图形视图框架
    当我们想让QGraphicsItems进行动画,并且使用QPropertyAnimation类。但是,QGraphicsItem没有从 QObject继承。一个好的解决方案是子类话你想要动画的图形项。而且本类也继承自QObject。QPropertyAnimation能被使用在 QGraphicsItems中。以下示例显示了怎么去做。另一个可能是去继承QGraphicsWidget,QGraphicsWidget是一个 QObject。
    class Pixmap : public QObject, public QGraphicsPixmapItem
    {
               Q_OBJECT
               Q_PROERTY(QPointF pos READ pos WRITE setPos)
               ……
    正如前所述,我们要定义的属性是要进行动画的属性。

    松弛曲线
    前边提到过,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

    把动画结合在一起
    一个应用程序通常包含多个动画,例如,你可能希望同时移动许多graphic items或者一个个按照串行的方式的移动他们
    子类QAnimationGroup(QSequentialAnimationGroup和QParallelAnimationGroup)可以包含其它animations,这样这些animations可以串行或者并行的触发了

    并行显示的例子

     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()函数将会启动它所管理的所有animations

    串行触发的例子

     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串行的播放所有的动画,当list中前一个动画播放完,它才启动下一个

    你可以把动画组animatio group添加到其他的动画组里面,这样可以创建一个动画结构树,树中已经制定了这些动画在播放时候彼此之间的关系


    动画和状态
    当使用状态机时候,我们可以将彼此状态之间用一个或者多个动画关联起来,使用QSignalTransition或者QEventTransition类,这两

    个类都继承自QAbstractTransition,QAbstractTransition提供了方便的函数addAnimation(),可以再状态转换触发时候播放一个或者

    多个动画animations

    我们也可以设置各个不同的状态的属性,而不用设置动画的startValues和endValue,下面是一个关联按钮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();

    常见类

    QtAbstractAnimation 抽象动画
    QtAnimationGroup 动画组
    QtEasingCurve 释放曲线
    QtParallelAnimationGroup 并行动画组
    QtPropertyAnimation 动画特性     可以使用Q_PROPERTRY来创建属性

    QtSequentialAnimationGroup 连续动画组
    QtVariantAnimation 变换动画
    QtGraphicsWidget 绘图部件
    QtAbstractState 抽象状态
    QtAbstractTransition 抽象转换
    QtActionState 动作状态
    QtEventTransition 事件转换
    QtFinalState 完成状态
    QtHistoryState 历史状态
    QtKeyEventTransition 键盘事件转换
    QtMouseEventTransition 鼠标事件转换
    QtSignalEvent 信号事件
    QtSignalTransition 信号转换
    QtState 状态
    QtStateAction 状态动作
    QtStateFinishedEvent 状态动作完成事件
    QtStateFinishedTransition 状态动作完成事件
    QtStateInvokeMethodAction 状态请求方法动作
    QtStateMachine 状态机器
    ---------------------
    作者:seanyxie
    来源:CSDN
    原文:https://blog.csdn.net/seanyxie/article/details/6173337
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    krpano--控制热点跳转到场景的指定视角
    bzoj 4237: 稻草人 -- CDQ分治
    bzoj 4176: Lucas的数论 -- 杜教筛,莫比乌斯反演
    bzoj 3545/3551: [ONTAK2010]Peaks -- 主席树,最小生成树,倍增
    bzoj 4627: [BeiJing2016]回转寿司 -- 权值线段树
    bzoj 1901: Zju2112 Dynamic Rankings -- 主席树,树状数组,哈希
    bzoj 3252: 攻略 -- 长链剖分+贪心
    bzoj 5055: 膜法师 -- 树状数组
    bzoj 1006: [HNOI2008]神奇的国度 -- 弦图(最大势算法)
    bzoj 1176: [Balkan2007]Mokia&&2683: 简单题 -- cdq分治
  • 原文地址:https://www.cnblogs.com/senior-engineer/p/11157326.html
Copyright © 2011-2022 走看看