Qt:在QML中使用Animator,让动画无卡顿

之前有说如果使用Qt的PropertyAnimation做Material曲线动画。

传送门: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,应该说是一个互相补充。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值