Qt终结者之QML动画

Posted yccheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt终结者之QML动画相关的知识,希望对你有一定的参考价值。

前言

使用QML差不多2年了,在使用过程中深深的感受到QML的强大与便捷,让我深陷其中,不能自拔。其中QML相比传统的界面最大的优势就是便捷的动画效果与炫酷的粒子效果,让QML做出来的界面能媲美WPF和各种JS前端框架的效果。下面我们就开始进入QML动画美妙的世界吧。

更现代的程序界面

与传统的界面相比,现代化的程序界面的特色是更加鲜艳的色彩,以及更加丰富的动画。QML设计的目的就是用来创建Fluid UIs(流体界面),所谓流体界面,就是UI组件是动态的,而不会突然出现、消失或跳转,QML的动画效果就很好的实现了流体界面的要求。

QML动画实现方法

在QML中,实现动画最常用的是State(状态)&Transactions(过渡) 与 Animating Properyty Changes(属性改变动画)这两种方法。

1、State & Transactions(状态与过渡)

QML可以在组件中声明各种State(状态),在状态中可以包含该组件所需修改的属性值,当我们想改变组件的属性值时,只需该组件的State即可。Transaction(过渡)用来设置状态改变时的动画,常与State配合使用。创建一个Transaction对象,然后将其添加到组件的transcation属性中。使用方法如下:

以下代码展示的是使用State&Transactions方法实现一个页面切换的动画效果。

Window {
    visible: true
    width: 400; height: 300
    title: "Animation"

    Rectangle { anchors.fill: parent; color: "green" }

    Rectangle {
        id: pageA
        color: "red"
        width: parent.width; height: parent.height
        
        // 创建2个状态"show","hide"分别表示显示界面和隐藏界面
        states: [
            // 将PageA的属性y赋值为0,opacity赋值为1以实现显示的效果
            State { 
                name: "show"; PropertyChanges { target: pageA; y: 0; opacity: 1 }
           },
            // 将PageA的属性y赋值为-height,opaticy赋值为0以实现窗口向上移动并消失的效果
            State {
                name: "hide"; PropertyChanges { target: pageA; y: -height; opacity: 0 }
           }
        ]

       state: "show"

       transitions: Transition {
           PropertyAnimation { properties: "y,opacity"; duration: 1000; easing.type: Easing.InOutBack }
             }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            if(pageA.state == "show")
                pageA.state = "hide"
            else
                pageA.state = "show"
        }
    }  
}        

pageA的状态由”show”改变为”hide”时,PropertyChanges{target:pageA;y:-height;opacity:0}执行,将属性y改为-heightopacity改为0

当属性改变时,PropertyAnimation{properties:"y,opacity";duration:1000;easing.type:Easing.InOutBack}被执行,产生动画效果。

2、Animating Property Changes(属性改变动画)

在属性上使用Behaviors(行为)关键字,指定在该属性改变时使用动画。修改以上代码使用Behaviors实现相同的效果。

Window {
    visible: true
    width: 400
    height: 300
    title: qsTr("Animation")

    Rectangle {
        id: pageB
        color: "green"
        anchors.fill: parent
    }

    Rectangle {
       id: pageA
       color: "red"
       width: parent.width
       height: parent.height
    // 给y属性改变安装动画
       Behavior on y { PropertyAnimation { duration: 1000; easing.type: Easing.InOutBack } }
    // 给opacity属性改变安装动画
       Behavior on opacity { PropertyAnimation{ duration: 1000 } }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            if (pageA.y == 0) {
                pageA.y = -pageA.height
                pageA.opacity = 0
            } else {
                pageA.y = 0
                pageA.opacity = 1
            }
        }
}

有些情况下还可以通过enabled属性来停用Behavior。注意这里的PropertyAnimationfromto属性是不需要定义的,因为这些值已经提供了,分别是Rectangle的当前值和onClicked处理器中设置的新值。

3、其他动画使用方法

3.1 动画作为属性值的来源

一个动画被应用为属性值的源(property value source),要使用动画on属性语法。

Window {
    visible: true
    width: 400
    height: 300
    title: qsTr("Animation")

    Rectangle {
        id: pageB
        color: "green"
        anchors.fill: parent
    }

    Rectangle {
        width: 100;
        height: 100
        color: "red"
        //启动后开始动画
        PropertyAnimation on x {to: 50; duration: 1000; loops: Animation.Infinite}
        PropertyAnimation on y {to: 50; duration: 1000; loops: Animation.Infinite}
    }
}

3.2 在信号处理器中创建一个动画,并在接收到信号时触发

Window {
    visible: true
    width: 400
    height: 300
    title: qsTr("Animation")

    Rectangle {
        id: pageB
        color: "green"
        anchors.fill: parent
    }

    Rectangle {
        id: rect
        width: 100;
        height: 100
        color: "red"

        MouseArea {
            anchors.fill: parent
            onClicked: PropertyAnimation {
                target: rect
                properties: "x,y"
                to: 50
                duration: 1000
            }
        }
    }
}

因为动画没有绑定到一个特定的对象或者属性,所以必须指定targetproperty(或者targetsproperties)属性的值。而且还需要使用to属性来指定新的xy的值。

3.3 独立动画

动画也可以像一个普通的QML对象一样进行创建,而不需要绑定到任何特定的对象和属性。

Window {
    visible: true
    width: 400
    height: 300
    title: qsTr("Animation")

    Rectangle {
        id: pageB
        color: "green"
        anchors.fill: parent
    }

    Rectangle {
        id: rect
        width: 100;
        height: 100
        color: "red"

        PropertyAnimation {
            id: animation
            duration: 1000
        }

        MouseArea {
            anchors.fill: parent
            onClicked: {
                animation.target = rect
                animation.properties = "x,y"
                animation.to = 50
                animation.start()
            }
        }
    }
}

一个独立的动画对象默认是没有运行的,必须使用running属性或者start()stop()函数来明确地运行它。因为动画没有绑定到一个特殊得对象或属性上,所以必须定义targetproperty(或者targetsproperties)属性的值。也需要用to属性来指定新的xy值。对于动画在不是一对一对象属性进行动画而且动画需要明确开始和停止的情况下是非常有用的。

动画元素

所有的动画都继承自Animation元素,尽管无法直接创建Animation对象,不过它为动画元素提供了必要的属性和函数。它允许使用running属性和start()stop()函数来控制动画的开始和停止,也可以通过loops属性定义动画的循环次数。

PropertyAnimation是用来为属性提供动画的最基本的动画元素,可以用来为realintcolorrectpointsizevector3d等属性设置动画,被NumberAnimationcolorAnimationRotationAnimationVector3dAnimation等元素继承。NumberAnimationrealint属性提供了更高效的实现;Vector3dAnimationvector3d属性提供了更高效的支持;而ColorAnimationRotationAnimation分别对colorrotation属性变化动画提供了特定的属性支持。

1. ColorAnimation允许颜色值设置fromto属性。

Rectangle {
        id: rect
        width: 100;
        height: 100
        color: "green"
    // 启动运行,由绿色变为红色
        ColorAnimation on color { from: "green"; to: "red"; duration: 1000 }
}

2. RotationAnimation允许设定旋转的方向。

Rectangle {
        id: rect
        width: 100;
        height: 100
        color: "red"
        anchors.centerIn: parent
    // 启动运行,顺时针旋转90°
        RotationAnimation on rotation { to: 90; duration: 1000; direction: RotationAnimation.Clockwise }
    }

3. SmoothedAnimation: 它是一个专门的NumberAnimation,当目标值改变时在动画中为其提供了一个平滑的变化;

4. SpringAnimation: 提供了一个像弹簧一样的动画,可以设置mass、damping和epsilon等属性

5. ParentAnimation: 用来在改变父项目时产生动画(对应ParentChange元素)

 6. AchorAnimation: 用来在改变锚时产生动画(对应AnchorChanges元素)

对于任何基于PropertyAnimation的动画都可以通过设置easing属性来控制在属性值动画中使用的缓和曲线。它们可以影响这些属性值的动画效果,提供一些如反弹、加速和减速等视觉效果。OutBounce来创建一个动画到达目标值时的反弹效果。

组合动画

多个动画可以组合成一个单一的动画,这可以使用ParallelAnimation或者SequentialAnimation动画组元素中的一个实现。在ParallelAnimation中的动画会同时进行,而在SequentialAnimation中的动画会一个个地运行。想要运行多个动画,可以在一个动画组中定义。以下代码分别表示串行动画和并行动画。

Window {
    visible: true
    width: 400
    height: 300
    title: qsTr("Animation")

    Rectangle {
        id: pageB
        color: "green"
        anchors.fill: parent
    }

    Rectangle {
        id: rect
        width: 100
        height: 100
        color: "red"
        // 串行动画
        SequentialAnimation {
            id: animation
            //
            NumberAnimation {
                target: rect
                properties: "x,y"
                to: 50
                duration: 1000
            }

            ColorAnimation {
                target: rect
                properties: "color"
                to: "blue"
                duration: 1000
            }
        }

        MouseArea {
            anchors.fill: parent
            onClicked: animation.start()
        }
    }
}
Window {
    visible: true
    width: 400
    height: 300
    title: qsTr("Animation")

    Rectangle {
        id: pageB
        color: "green"
        anchors.fill: parent
    }

    Rectangle {
        id: rect
        width: 100
        height: 100
        color: "red"
        // 串行动画
        ParallelAnimation {
            id: animation
            //
            NumberAnimation {
                target: rect
                properties: "x,y"
                to: 50
                duration: 1000
            }

            ColorAnimation {
                target: rect
                properties: "color"
                to: "blue"
                duration: 1000
            }
        }

        MouseArea {
            anchors.fill: parent
            onClicked: animation.start()
        }
    }
}

其他动画元素

QML还为动画提供了其他一些有用的元素

1. PauseAnimation: 在动画中间进行暂停

 2. ScriptAnimation: 允许在动画中执行javascript,也可以和StateChangeScript一起使用来重用已经存在的脚本

 

 

以上是关于Qt终结者之QML动画的主要内容,如果未能解决你的问题,请参考以下文章

Qt基于Qml图像帧动画播放

如何在QML(QT Creator)中使用发光脉动效果制作元素动画?

qt qgraphicsWidget注册为qml类型并绘制图形,但添加任何动画后图形不流畅

Qt在线讲座之QML脚本书写规范

qt qml中PropertyAnimation的几种使用方法

如何在 QML 中动画添加和删除元素到布局?