Qt:在QML中使用Animator,让动画无卡顿
2017-08-31 11:22
721 查看
之前有说如果使用Qt的PropertyAnimation做Material曲线动画。
传送门:
PropertyAnimation是Qt提供的属性动画,用的非常广泛。可以适用于很多场合,比如说X的移动,甚至自定义属性的修改。他还有很多派生类,比如说NumberAnimation、ColorAnimation,这里不一一展开。
但是Animation有一个遗憾,就是它运行在GUI线程。
为什么说这是一个遗憾,因为按照我们一般的开发情况,并不能充分利用异步API,或者某些操作就是卡顿(比如说QML代码编译),这些都会导致GUI线程无法正常刷新界面。这样我们的60FPS就没了。
比如一个操作,需要200MS,按照60FPS的16MS间隔,这样就掉了12帧,已经肉眼可以明显分辨了。如果这个动画是从左移动到右边这种动画,那么这个动画看上去会非常不舒服。
既然QML是一个专门做界面的语言,那么这种问题,Qt自然已经考虑了,并且对此提供了一个解决方案,就是Animator。介绍如下:
其中我们需要关心的重点是
也就是说,动画可以运行在渲染线程,而非主线程。这就意味着动画可以不受主线程卡顿的影响,流畅的运行。
来一个示例:
在这个示例中,创建了两个紫色的Rectangle,并且在鼠标点击后,从左移动到右边。主要关注:
上面的Rectangle,使用NumberAnimation,指定property为x,进行动画
下面的Rectangle,使用XAnimator,进行动画
每100ms,会让gui线程休眠50ms,来模拟卡顿。
运行效果如下:
* CSDN我没找到哪里上传视频,这个gif录制出来差异就不明显了 *
从这里可以看出,上面的Rectangle,从左到右是一点点卡过去,毫无流畅可言。甚至因为卡顿,都没能在预设的时间内完成动画。
而下面的Rectangle从左到右,丝滑般流畅,无卡顿。
至此,我们通过简单的,将Animation替换为Animator,就解决了gui线程卡顿带来的界面卡顿问题。
但是,Animator不是万能的,也有局限,使用的时候务必注意:
Animator支持的类型很少,只有x、y、opacity、rotation、scale和uniform,不支持自定义类型
Animator依赖渲染线程,程序必须是多线程渲染模式才可以使用Animator,不然效果和普通的Animation一样。不过现在Quick程序一般都已经是多线程渲染了。
Animator不支持reversible
如果Animation和Animator混用,很有可能让动画播放上不一致(即使设置的时间是一样的),就是Animator负责的动画已经完成了,但是Animation的动画因为卡顿或其他原因,还在进行中。例如上面的那个示例。
总的说,Animator是一种优化手段,但是它并不能完全替代Animation,应该说是一个互相补充。
传送门:
http://blog.csdn.net/wsj18808050/article/details/72869043
PropertyAnimation是Qt提供的属性动画,用的非常广泛。可以适用于很多场合,比如说X的移动,甚至自定义属性的修改。他还有很多派生类,比如说NumberAnimation、ColorAnimation,这里不一一展开。
但是Animation有一个遗憾,就是它运行在GUI线程。
为什么说这是一个遗憾,因为按照我们一般的开发情况,并不能充分利用异步API,或者某些操作就是卡顿(比如说QML代码编译),这些都会导致GUI线程无法正常刷新界面。这样我们的60FPS就没了。
比如一个操作,需要200MS,按照60FPS的16MS间隔,这样就掉了12帧,已经肉眼可以明显分辨了。如果这个动画是从左移动到右边这种动画,那么这个动画看上去会非常不舒服。
既然QML是一个专门做界面的语言,那么这种问题,Qt自然已经考虑了,并且对此提供了一个解决方案,就是Animator。介绍如下:
Animator types are different from normal Animation types. When using an Animator, the animation can be run in the render thread and the property value will jump to the end when the animation is complete.
其中我们需要关心的重点是
the animation can be run in the render thread
也就是说,动画可以运行在渲染线程,而非主线程。这就意味着动画可以不受主线程卡顿的影响,流畅的运行。
来一个示例:
import QtQuick 2.6 import QtQuick.Window 2.2 Window { visible: true width: 600 height: 400 Rectangle { id: rectangle1 x: 50 y: 50 width: 100 height: 100 color: "#ff00ff" } Rectangle { id: rectangle2 x: 50 y: 250 width: 100 height: 100 color: "#ff00ff" } NumberAnimation { id: animation target: rectangle1 property: "x" from: 50 to: 450 duration: 1000 } XAnimator { id: animator target: rectangle2 from: 50 to: 450 duration: 1000 } Timer { id: timer interval: 100 repeat: true running: animation.running onTriggered: { Helper.msleep( 50 ); } } MouseArea { anchors.fill: parent onClicked: { animation.running = true; animator.running = true; timer.running = true; } } }
在这个示例中,创建了两个紫色的Rectangle,并且在鼠标点击后,从左移动到右边。主要关注:
上面的Rectangle,使用NumberAnimation,指定property为x,进行动画
下面的Rectangle,使用XAnimator,进行动画
每100ms,会让gui线程休眠50ms,来模拟卡顿。
运行效果如下:
* CSDN我没找到哪里上传视频,这个gif录制出来差异就不明显了 *
从这里可以看出,上面的Rectangle,从左到右是一点点卡过去,毫无流畅可言。甚至因为卡顿,都没能在预设的时间内完成动画。
而下面的Rectangle从左到右,丝滑般流畅,无卡顿。
至此,我们通过简单的,将Animation替换为Animator,就解决了gui线程卡顿带来的界面卡顿问题。
但是,Animator不是万能的,也有局限,使用的时候务必注意:
Animator支持的类型很少,只有x、y、opacity、rotation、scale和uniform,不支持自定义类型
Animator依赖渲染线程,程序必须是多线程渲染模式才可以使用Animator,不然效果和普通的Animation一样。不过现在Quick程序一般都已经是多线程渲染了。
Animator不支持reversible
如果Animation和Animator混用,很有可能让动画播放上不一致(即使设置的时间是一样的),就是Animator负责的动画已经完成了,但是Animation的动画因为卡顿或其他原因,还在进行中。例如上面的那个示例。
总的说,Animator是一种优化手段,但是它并不能完全替代Animation,应该说是一个互相补充。
相关文章推荐
- 在QT/QML中使用FontAwesome做图标显示
- Android动画学习(三)之使用ValueAnimator和ObjectAnimator实现动画实例
- QT c++程序使用qml的两种方法
- Qt:在QML中自定义贝塞尔动画曲线
- 模拟物体(汽车)任意方向和速度移动平面动画__(使用Qt 实现)
- 如何使用iOS 10的UIViewPropertyAnimator做动画
- <Linux+Qt>在Widget中使用qlabel显示图片与动画
- QML笔记整理——在Qt/C++应用中使用QML
- Qt:解决QtQuick(QML)程序,在虚拟机或者某些环境下,动画速度过快的问题
- 使用ObjectAnimator开发打开、关闭书本动画
- 使用Unity新版动画系统Animator实现三连击
- 属性动画ValueAnimator和ObjectAnimator的使用
- unity 新的动画系统 Animator的使用(原)
- Android动画学习(三)之使用ValueAnimator和ObjectAnimator实现动画实例
- Qt qml中使用listView加载组件问题
- Qt-第一个QML程序-4-自定义按钮类,动画,状态
- 属性动画05-ObjectAnimator的高级使用
- Qt实例分析——C++定义的类创建为供QML使用的插件
- Qt移动应用开发(三):使用精灵图片实现帧动画
- Android进阶学习-属性动画(使用Animator封装特效工具类2)