目录
- 1.前言
- 2.原理
- 3.属性动画
- 4.并行执行的动画
- 5.顺序执行的动画
- 6.扩展属性动画支持的数据类型
1.前言
为软件适当的添加一些动画,能够提高软件的用户体验。在使用Qt框架开发软件时,我们可以用Qt提供的动画框架来为QWidget等UI元素添加动画效果。本文从动画原理开始将详细介绍如何在软件中实现动画效果。
2.原理
上图是Qt动画框架中重要的几个类,其中QAbstractAnimation是所有动画类的基类,该类中封装了动画的基本动作如开始、结束、暂停。在创建动画时主要用到 QPropertyAnimation、QParallelAnimationGroup、QSequentialAnimationGroup 这三个类。具体功能描述如下。
- QPropertyAnimation 用来设置具体的动画。
- QParallelAnimationGroup 若一个复杂动画是由多个动画同时动作实现的,则用这个类管理多个属性动画。
- QSequentialAnimationGroup 若一个复杂动画是由多个动画按照顺序执行实现的,则用这个类管理多个属性动画。
如果一个动画足够复杂,还可以将QParallelAnimationGroup的实例添加到QSequentialAnimationGroup中来实现,反之亦然。
3.属性动画
Qt中的属性是指用Q_PROPERTY宏声明的类成员,声明了属性成员的类必须是QObject的子类。QPropertyAnimation 类通过在动画对象的某个属性两值(动画开始和结束时的属性值)之间进行插值使得属性值随时间而改变。这种动画方式提供了极大的灵活性,假如我想要某个值随时间变化,我可以把这个值声明为QObject子类的一个属性。下面是一个属性动画的示例:
//第一个参数是要执行动画的目标对象,第二个参数是要动画的属性名称。
QPropertyAnimation *pAnimation = new QPropertyAnimation(ui->pushButton, "geometry");
//设置动画属性的开始值
pAnimation->setStartValue(QRect(0,0, 200, 100));
//设置动画属性的结束值
pAnimation->setEndValue(QRect(200,200, 300, 200));
//设置动画执行时间
pAnimation->setDuration(2000);
//设置动画执行结束后的操作,保留或者删除动画,这里选择执行完动画后,删除动画实例pAnimation。
pAnimation->start(QAbstractAnimation::DeleteWhenStopped);
4.并行执行的动画
用QParallelAnimationGroup来同时执行多个动画,下面的示例程序通过同时改变QWidget的位置属性pos和大小属性size来实现边移动边改变QWidget大小的效果。
//改变位置动画
QPropertyAnimation *pAnimationPos = new QPropertyAnimation(ui->pushButton, "pos");
pAnimationPos->setStartValue(QPoint(0,0));
pAnimationPos->setEndValue(QPoint(200,200));
pAnimationPos->setDuration(4000);
//改变大小动画
QPropertyAnimation *pAnimationSize = new QPropertyAnimation(ui->pushButton, "size");
pAnimationSize->setStartValue(QSize(0,0));
pAnimationSize->setEndValue(QSize(200,200));
pAnimationSize->setDuration(4000);
//同时执行两个动画
QParallelAnimationGroup *pAnimation = new QParallelAnimationGroup(this);
pAnimation->addAnimation(pAnimationPos);
pAnimation->addAnimation(pAnimationSize);
pAnimation->start(QAbstractAnimation::DeleteWhenStopped);
5.顺序执行的动画
用QSequentialAnimationGroup来执行顺序动画,下面的示例程序通过先时改变QWidget的位置属性pos,再改变尺寸大小属性size来实现先移动再缩小的动画效果。
//先改变位置
QPropertyAnimation *pAnimationPos = new QPropertyAnimation(ui->pushButton, "pos");
pAnimationPos->setStartValue(QPoint(0,0));
pAnimationPos->setEndValue(QPoint(200,200));
pAnimationPos->setDuration(2000);
//再改变尺寸大小
QPropertyAnimation *pAnimationSize = new QPropertyAnimation(ui->pushButton, "size");
pAnimationSize->setStartValue(QSize(200,200));
pAnimationSize->setEndValue(QSize(50,50));
pAnimationSize->setDuration(2000);
//顺序执行动画
QSequentialAnimationGroup *pAnimation = new QSequentialAnimationGroup(this);
pAnimation->addAnimation(pAnimationPos);
pAnimation->addAnimation(pAnimationSize);
pAnimation->start(QAbstractAnimation::DeleteWhenStopped);
6.扩展属性动画支持的数据类型
属性动画继承自QVariantAnimation ,虽然属性的数据类型是QVariant类型,但并不是所有的QVariant类型都支持动画,支持动画的QVariant类型如下:Int、UInt、Double、Float、QLine、QLineF、QPoint、QPointF、QSize、QSizeF、QRect、QRectF、QColor。
如果一个类成员的数据类型是QVariant支持的,但该类型不支持属性动画,可以用下面的方式注册该数据类型来使它支持动画。
//这里假设QColor类型不支持属性动画
QVariant myQPaletteInterpolator(const QPalette &start, const QPalette &end, qreal progress)
{
//根据progress来计算新的QPalette值
return QPalette(...);
}
...
//下面这行代码最好写在构造函数中
qRegisterAnimationInterpolator<QPalette>(myQPaletteInterpolator);
以上就是本文的所有内容了,有不对的地方,欢迎指正,谢谢!