Qt的动画即不断地改变对象的属性,从而实现过渡。就像太阳从东方升起西方落下一样,只要给它设置起点和终点,再中间插入几个点,它就沿着这几个点组成的线运动,从而形成连续的图像。
qt中可运用动画的有widgets和qobject。
动画中主要的类的继承关系如下:
我们将动画中的类分为如下几个部分:
以下三个用于形成动画:
QPropertyAnimation、QVariantAnimation、QPauseAnimation
辅助的,用于提供参数:
QEasingCurve、QTimeLine
将动画分组:
QAnimationGroup、QParallelAnimationGroup、QSequentialAnimationGroup
基类(鸡肋):
QAbstractAnimation
以上类都继承自QAbstractAnimation,因面它们有如下的公共槽 Public Slots
void | pause() |
void | resume() |
void | setCurrentTime(int msecs) |
void | setPaused(bool paused) |
void | start(QAbstractAnimation::DeletionPolicy policy = KeepWhenStopped) |
void | stop() |
————————————————————————————————————————————
先谈谈QEasingCurve,这个类提供了动画在时间间隔内的变化曲线。
主要用到它的各种type,点此查看,这里提供了近五十个已定义的曲线。
以第二个为例:
Constant | Value |
---|---|
QEasingCurve::InQuad | 1 |
Easing curve for a quadratic (t^2) function: accelerating from zero velocity.
这是一个数学中t的平方二次曲线,progress轴是动画进度
假设一个将某个对象的长度由0变为100px的动画过程,设置它完成这个过程的时间间隔为10秒。它的变化曲线为上图这个InQuad二次方线,则动画运行到3秒时,进行了整个过程的十分之三,即x轴progress为0.3,它对应的value纵坐标为0.3的平方为,0.09,则当前这个对象的长度为100px-0的差乘上0.09等于9px。
当然,也许我们编程过程中并不需要这样计算,但能明白这个图线也是好的,看到这个图时,只要能感觉到使用它时,我们的动画是一个先慢后快的过程就行了。
这个类先讲到这里,我也暂不清楚它其它函数的用法,以后补上……
——————————————————————————————————————————
由于QVariantAnimation是一个抽象的类,所以不可以直接使用,但QPropertyAnimation是继承自它,而它又继承自QAbstractAnimation。所以也继承了它们的一些方法与属性。
查看这三个类,我们知道QPropertyAnimation有很多有用的方法:
void setDuration(int msecs)设置动画运行时间,即上面例子中的10秒
void setEasingCurve(const QEasingCurve & easing)设置变化曲线,即是我们上面说的EasingCurve
void setStartValue(const QVariant & value)设置开始值,如上述例子中的对象的长度由0
void setKeyValueAt(qreal step, const QVariant & value)设置动画的关键帧,可灵活地设置在动画进度的哪个点上,step即图像中的progress值,在0-1间
void setKeyValues(const KeyValues & keyValues) 设置动画的多个关键帧
void setEndValue(const QVariant & value)结束值,即上例的100px
来自QAbstractAnimation
voidsetDirection(Direction direction) 运行方向,默认向前(QAbstractAnimation::Forward),也可以向后QAbstractAnimation::Backward
void setLoopCount(int loopCount) 设置动画循环次数,不运行,设为0,不断运行(-1),默认为1次。
来自它本身:
voidsetTargetObject(QObject * target)//设置要进行动画的对象
voidsetPropertyName(const QByteArray & propertyName)//设置要进行动画的对象的属性
以下进行我们的第一个测试例子(一个任意耍的按钮):
新建一个带ui的dilog工程,在界面上拖入一个QPushButton,在dialog.CPP中加进#include <QPropertyAnimation>
在它的构造函数中加进:
QPropertyAnimation *animation = new QPropertyAnimation(ui->pushButton, "geometry");
//用到了它的构造函数QPropertyAnimation(QObject * target, const QByteArray & propertyName, QObject * parent = 0)
//也可以如下
/*
QPropertyAnimation *animation = new QPropertyAnimation(this);
animation->setTargetObject(ui->pushButton);
animation->setPropertyName("geometry");
*/
animation->setDuration(5000);
animation->setEasingCurve(QEasingCurve::InQuad);
animation->setStartValue(QRect(0, 0, 200, 100));
animation->setKeyValueAt(0.4,QRect(50, 50, 200, 100));
animation->setEndValue(QRect(50, 50, 300, 150));
//animation->setDirection(QAbstractAnimation::Backward);
animation->setLoopCount(2);
animation->start();
程序一编译完成即开始运行
界面的pushButton有geometry几何属性,它控制着按钮的(x,y,width,height),运行后,按钮将从0,0点开始,连续地移动到50,50坐标位置,我们在此设置了keyValue,之后,位置不变,按钮的宽高逐渐变大至300,150.
由于设置了loopCount,所以这个过程完成后,又运行了一遍后才停止。
如果加上被注释掉的setDirection设置后,整个过程将先缩小再移动……
——————————————————————————————————————————
以下讲动画的分组运行机制
QParallelAnimationGroup为并行动画组、QSequentialAnimationGroup为时序动画组,分别表示多个动画的并联与串联。
它们都继承自QAnimationGroup,QAnimationGroup有如下重要方法
void | addAnimation(QAbstractAnimation * animation)添加动画 |
QAbstractAnimation * | animationAt(int index) const返回组中某索引的动画对象 |
int | animationCount() const组中动画数量 |
void | clear()清空 |
int | indexOfAnimation(QAbstractAnimation * animation) const 某动画在组中的索引 |
void | insertAnimation(int index, QAbstractAnimation * animation)插入一个动画对象 |
void | removeAnimation(QAbstractAnimation * animation)移除 |
QAbstractAnimation * | takeAnimation(int index) 返回某索引的动画对象,同时移除了它 |
以并行动画为例
QPropertyAnimation *animation1 = new QPropertyAnimation(ui->pushButton1, "geometry");
animation1->setDuration(5000);
animation1->setEasingCurve(QEasingCurve::InQuad);
animation1->setStartValue(QRect(0, 0, 200, 100));
animation1->setEndValue(QRect(50, 50, 300, 150));
QPropertyAnimation *animation2 = new QPropertyAnimation(ui->pushButton2, "geometry");
animation2->setDuration(5000);
animation2->setEasingCurve(QEasingCurve::InQuad);
animation2->setStartValue(QRect(400, 0, 100, 100));
animation2->setEndValue(QRect(100, 100, 150, 150));
QParallelAnimationGroup *group = new QParallelAnimationGroup;
group->addAnimation(animation1);
group->addAnimation(animation2);
group->start();
我们创建了两个动画animation1与animation2,分别用来控制界面上的两个按钮,当QParallelAnimationGroup并行动画start时,它们同时开始改变,类似的,如果使用QSequentialAnimationGroup串行,则animation1先运行,animation1运行完成后,animation2才开始
这里再补充一下QPauseAnimation,这个类主要用于QSequentialAnimationGroup这个时序串联的动画运行时暂停一些时间,只要创建QPauseAnimation对象后,加入这个组就行了。
比如
QPauseAnimation *p=new QPauseAnimation ;
group->addAnimation(p);
QSequentialAnimationGroup也提供了如下能直接运用的延时公有函数,具有相同的作用,:
QPauseAnimation * addPause(int msecs)
QPauseAnimation * insertPause(int index, int msecs)
无论何种方式加了延时,animationCount都会增一
相关源码地址:http://pan.baidu.com/s/1tHLbf