【二-3-1】Qt 动画框架——基础
0 概览
0.1)要点
0.1.1)实现:通过控制对象的属性来实现。
0.1.2)应用:在窗口和其它基于 QObject 的对象上。
0.2)主要类关系图
0.3)关于使用动画
0.3.1)使用缓和曲线对属性插值。
0.3.2)要对值使用动画,可创建 QObject 的子类,并在类中将该值定义为属性。
0.3.3)Qt 现在支持的可以进行插值的 QVariant 类型有:Int、Uint、Double、Float、QLine、QLineF、QPoint、QPointF、QSize、QSizeF、QRect、QRectF 和 QColor 等。
0.3.4)动画也被设计为状态机的一部分,1 + 1 > 2 。
1 属性动画 QPropertyAnimation
1.1)属性动画使用示例(作用于对象的属性变化过程)
1 QPushButton pbt("我是 QObject 的子类"); 2 pbt.show(); 3 QPropertyAnimation pa(&pbt, "geometry"); 4 pa.setDuration(16888); // ms 5 pa.setStartValue( QRect(0, 0, 200, 100) ); 6 pa.setEndValue( QRect(100, 100, 400, 200) ); 7 pa.start(); 8 9 // 还可以调用 setKeyValueAt() 函数在动画中间为属性设置值,将前面 setStartValue 和 setEndValue 用下面3条语句替代。 10 pa.setKeyValueAt(0, QRect(0, 0, 100, 100)); 11 pa.setKeyValueAt(0.8, QRect(125, 125, 200, 200)); 12 pa.setKeyValueAt(1, QRect(250, 250, 300, 300)); 13 14 // 动画框架的其它常用函数 15 //pause() // 暂停 16 //resume() // 恢复 17 //stop() // 停止 18 //setDirection() // 设置方向 19 //setLoopCount() // 设置循环次数
1.2)使用缓和曲线(作用于对象的属性变化过程)
1 pa.setEasingCurve(QEasingCurve::OutBouce); // QEasingCurve 提供了四十多种曲线,也可自定义。Qt 提供的 Easing Curve Example 例程演示了各种缓和曲线的效果。
2 动画组 QAnimationGroup
2.1)QAnimationGroup 的两个子类 QSequentialAnimationGroup 和 QParallelAnimationGroup 分别实现了串行动画组和并行动画组。
2.2)串行动画组(先后顺序执行的一组动画)示例
1 QPushButton button("我是 QObject 的子类"); 2 button.show(); 3 4 QPropertyAnimation animation1(&button, "geometry"); 5 animation1.setDuration(5000); 6 animation1.setStartValue( QRect(0, 0, 200, 100) ); 7 animation1.setEndValue( QRect(200, 200, 400, 200) ); 8 animation1.setEasingCurve(QEasingCurve::OutBouce); 9 10 QPropertyAnimation animation2(&button, "geometry"); 11 animation2.setDuration(2500); 12 animation2.setStartValue( QRect(0, 0, 200, 100) ); 13 animation2.setEndValue( QRect(200, 200, 400, 200) ); 14 animation2.setEasingCurve(QEasingCurve::OutBouce); 15 16 QSequentialAnimationGroup group; 17 group.addAnimation(animation1); 18 group.addAnimation(animation2); 19 group.start();
2.3)并行动画组(同步执行的一组动画)示例
1 QPushButton button1("1我是 QObject 的子类"); 2 button1.show(); 3 4 QPushButton button2("2我是 QObject 的子类"); 5 button2.show(); 6 7 QPropertyAnimation animation1(&button1, "geometry"); 8 animation1.setDuration(5000); 9 animation1.setStartValue( QRect(0, 0, 200, 100) ); 10 animation1.setEndValue( QRect(200, 200, 400, 200) ); 11 animation1.setEasingCurve(QEasingCurve::OutBouce); 12 13 QPropertyAnimation animation2(&button2, "geometry"); 14 animation2.setDuration(2500); 15 animation2.setStartValue( QRect(100, 100, 200, 100) ); 16 animation2.setEndValue( QRect(300, 300, 400, 200) ); 17 animation2.setEasingCurve(QEasingCurve::OutBouce); 18 19 QParallelAnimationGroup group; 20 group.addAnimation(animation1); 21 group.addAnimation(animation2); 22 group.start();
3 在图形视图框架中使用动画(配合这个 https://www.cnblogs.com/XieJX/p/16007930.html )
3.1)使用示例
// <a> 新建 QGraphicsObject 的子类
// <a.1> 子类的头文件 mygraphicsobject.h
1 #ifndef MYGRAPHICSOBJECT_H 2 #define MYGRAPHICSOBJECT_H 3 4 #include <QGraphicsObject> 5 6 class MyGraphicsObject : public QGraphicsObject 7 { 8 public: 9 MyGraphicsObject(QGraphicsObject *parent = 0); 10 QRectF boundingRect() const; 11 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr); 12 }; 13 14 #endif // MYGRAPHICSOBJECT_H
// <a.2> 子类的源文件 mygraphicsobject.cpp
1 #include "mygraphicsobject.h" 2 #include <QPainter> 3 4 MyGraphicsObject::MyGraphicsObject(QGraphicsObject *parent) : QGraphicsObject(parent) 5 { 6 7 } 8 9 QRectF MyGraphicsObject::boundingRect() const 10 { 11 qreal penWidth = 1; 12 return QRectF(-50 - penWidth / 2, -50 - penWidth / 2, 100 + penWidth, 100 + penWidth); 13 } 14 15 void MyGraphicsObject::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 16 { 17 painter->drawRect(boundingRect()); 18 }
// <b> 主程序 mian.cpp
1 #include <QApplication> 2 #include <QGraphicsScene> 3 #include <QGraphicsView> 4 #include "mygraphicsobject.h" 5 #include <QPropertyAnimation> 6 7 int main(int argc, char *argv[]) 8 { 9 QApplication a(argc, argv); 10 11 QGraphicsScene scene; 12 scene.setSceneRect( QRectF(-200, -200, 400, 400) ); 13 MyGraphicsObject *item = new MyGraphicsObject; 14 scene.addItem(item); 15 QGraphicsView view(&scene); 16 view.show(); 17 18 QPropertyAnimation animation(item, "rotation"); 19 animation.setDuration(3000); 20 animation.setStartValue(0); 21 animation.setEndValue(360); 22 animation.start(); 23 24 return a.exec(); 25 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理