qml之动态元素类型

文章目录

  • 动画
    • 例子
  • 应用动画
    • 例子
  • 缓动曲线
    • 例子
  • 动画分组
    • 例子
  • 嵌套动画
    • 代码
  • 状态和转换
    • 代码

动画

  • QMlL使用插值的方式控制属性的更改。
  • 动画是在指定的时间内一些列属性的持续变化。
    常用的动画类型元素动画:
  • PropertyAnimation:属性值改变播放动画
  • NumberAnimation:qreal_type值改变播放动画
  • ColorAnimation:颜色值改变播放动画
  • RotationAnimation:旋转值改变播放的动画
    Qt Quick还提供了一些特殊场景下需要使用的动画类型:
    PauseAnimation,SequentialAnimation,ParallelAnimation,AnchorAnimation,ParentAnimation,SmoothedAnimation ,SpringAnimation,PathAnimation,Vector3dAnimation
    对于更加复杂的动画,可能需要在播放动画时改变属性或者运行脚本。为此,QtQuick提供了action元素:
  • PropertyAction:在播放动画时改变属性
  • ScripAction:在播放动画时运行脚本

例子

import QtQuick
import QtQuick.Window

Image {
    id: root
    source: "../../images/background.png"

    property int padding: 40
    property bool running: false

    Image {
        id: qq
        source: "../../images/qq.png"
        x:root.padding;y:(root.height-height)/2

        NumberAnimation on x{
            to:root.width-qq.width-root.padding
            duration: 3000
            running: root.running
        }

        RotationAnimator on rotation{
            to:360
            duration: 3000
            running: root.running
        }

        OpacityAnimator on opacity{
            to:0
            duration: 3000
            running: root.running
        }
    }

    MouseArea{
        anchors.fill: root
        onClicked: root.running = true
    }
}

qml之动态元素类型_第1张图片

  • 应用于x和rotation、透明度属性的简单动画。
  • 每个动画的持续时间为3000毫秒。
  • x:将对象逐渐移动到右边的位置。
  • rotation:从当前角度运行到360度。
  • 透明度:从1到0
  • 三个动画并行运行,并在单击鼠标区域时启动。

应用动画

可以通过多种方式执行动画:

  • 属性上的动画:在元素完全加载后自动运行
  • 属性上的行为:属性值更改时自动运行
  • 独立动画:使用start()显式启动动画或将running设置为true时运行

例子

import QtQuick
import QtQuick.Window

Window {
    id:root
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    color:"gray"

    ClickableImageV2{
        id:qq1
        x:40;y:root.height-height
        source:"../../images/qq.png"
        text:"animation on property"

        NumberAnimation on y{
            to:40;duration:3000
        }
    }

    ClickableImageV2{
        id:qq2
        x:40+qq1.width+20;y:root.height-height
        source:"../../images/qq.png"
        text:"animation on property"

        Behavior on y{
            NumberAnimation{duration:3000}
        }

        onClicked: y=40
    }

    ClickableImageV2{
        id:qq3
        x:40+qq1.width+qq2.x;y:root.height-height
        source:"../../images/qq.png"
        text:"animation on property"

        NumberAnimation{
            id:anim
            target:qq3
            from:root.height-qq3.height
            to:40;duration:3000
            property:"y"
            running:area.pressed
        }

        MouseArea{
            id:area
            anchors.fill: parent
        }
    }
}

 第一个对象使用on<property>策略进行移动。动画立即开始。
 第二个对象使用Behavior on动画。此行为告诉属性它应该为值的每个更改设置动画。可以通过在行为元素上设置enabled:false来禁用该行为。
 第三个对象使用standalone动画。动画被定义为其自己的元素,几乎可以位于文档中的任何位置。

缓动曲线

qml之动态元素类型_第2张图片
属性的值更改可以由动画控制。缓动属性允许影响属性更改的插值曲线。
y轴:property
x轴:duration

例子

import QtQuick
import QtQuick.Window
import QtQuick.Layouts

Rectangle{
    id:root
    width: childrenRect.width
    height: childrenRect.height

    color:'gray'
    gradient: Gradient{
        GradientStop{position:0.0;color:root.color}
        GradientStop{position:1.0;color:Qt.lighter(root.color,1.5)}
    }

    ColumnLayout{
        spacing: 20
        Grid{
            spacing: 10
            columns:5

            EasingType{
                title:'Linear'
                easingType: Easing.Linear
                onClicked: {
                    animation.easing.type=easingType
                    box.toggle=!box.toggle
                }
            }
            EasingType{
                title:'InExpo'
                easingType: Easing.InExpo
                onClicked: {
                    animation.easing.type=easingType
                    box.toggle=!box.toggle
                }
            }
            EasingType{
                title:'OutExpo'
                easingType: Easing.OutExpo
                onClicked: {
                    animation.easing.type=easingType
                    box.toggle=!box.toggle
                }
            }
            EasingType{
                title:'InOutExpo'
                easingType: Easing.InOutExpo
                onClicked: {
                    animation.easing.type=easingType
                    box.toggle=!box.toggle
                }
            }
            EasingType{
                title:'InOutCubic'
                easingType: Easing.InOutCubic
                onClicked: {
                    animation.easing.type=easingType
                    box.toggle=!box.toggle
                }
            }
            EasingType{
                title:'SineCurve'
                easingType: Easing.SineCurve
                onClicked: {
                    animation.easing.type=easingType
                    box.toggle=!box.toggle
                }
            }
            EasingType{
                title:'InOutCirc'
                easingType: Easing.InOutCirc
                onClicked: {
                    animation.easing.type=easingType
                    box.toggle=!box.toggle
                }
            }
            EasingType{
                title:'InOutElastic'
                easingType: Easing.InOutElastic
                onClicked: {
                    animation.easing.type=easingType
                    box.toggle=!box.toggle
                }
            }
            EasingType{
                title:'InOutBack'
                easingType: Easing.InOutBack
                onClicked: {
                    animation.easing.type=easingType
                    box.toggle=!box.toggle
                }
            }
            EasingType{
                title:'InOutBounce'
                easingType: Easing.InOutBounce
                onClicked: {
                    animation.easing.type=easingType
                    box.toggle=!box.toggle
                }
            }
        }

        Rectangle{
            height:100
            Layout.fillWidth: true
            gradient: Gradient{
                GradientStop{position:0.0;color:'gray'}
                GradientStop{position:1.0;color:'green'}
            }
            Rectangle{
                id:box
                property  bool toggle
                anchors.verticalCenter: parent.verticalCenter
                width: 80;height:80
                gradient: Gradient{
                    GradientStop{position:0.0;color:'red'}
                    GradientStop{position:1.0;color:'yellow'}
                }

                x:toggle?20:root.width-width-20
                Behavior on x{
                    NumberAnimation{
                        id:animation
                        duration:1000
                    }
                }
            }
        }
    }

}

qml之动态元素类型_第3张图片
点击不同的曲线会有不同的动画效果。

动画分组

 分组有两种方式:并行或顺序。
可以使用SequentialAnimation或ParallelAnimation元素,它们充当其他动画元素的动画容器。这些分组动画本身就是动画。
qml之动态元素类型_第4张图片

例子

import QtQuick
import QtQuick.Window

Window {
    id:root
    width: 640
    height: 480
    visible: true
    title: qsTr("UFO")
    property int duration: 3000

    Image {
        source: "../../images/background.png"
        anchors.fill: parent
    }

    ClickableImageV3{
        id:ufo
        x:20;y:root.height-height
        source: "../../images/ufo.png"
        text:'UFO'
        onClicked: anim.restart()
    }

    ParallelAnimation/*SequentialAnimation*/{
        id:anim

        NumberAnimation{
            target: ufo
            property: 'y'
            from:root.height-ufo.height
            to:20
            duration: root.duration
        }

        NumberAnimation{
            target: ufo
            property: 'x'
            from:20
            to:500
            duration: root.duration
        }
    }
}

qml之动态元素类型_第5张图片

嵌套动画

 分组动画也可以嵌套。例如,一个连续动画可以有两个并行动画作为子动画。我们可以通过一个足球示例:

  • 从左到右的x平移(X1)
  • 从下到上的y平移(Y1),然后是从上到下的平移(Y2),带有一些弹跳
  • 在动画的整个持续时间内旋转360度(ROT1)
    qml之动态元素类型_第6张图片
     即我们可以将y的改变分成一次顺序动画,角度和x的变化与这次顺序动画为一个并行动画即可实现效果。

代码

import QtQuick
import QtQuick.Window

Item {
    id:root
    width: 480
    height: 300
    property int duration: 3000

    Rectangle{
        id:sky
        width: root.width
        height: 200
        gradient: Gradient{
            GradientStop{position:0.0;color:"#0080FF"}
            GradientStop{position:1.0;color:"#66CCFF"}
        }
    }

    Rectangle{
        id:ground
        anchors.top: sky.bottom
        anchors.bottom:root.bottom
        width: root.width
        gradient: Gradient{
            GradientStop{position:0.0;color:"#00FF00"}
            GradientStop{position:1.0;color:"#00803F"}
        }
    }

    Image {
        id: ball
        source: "../../images/soccer_ball.png"
        scale:0.5
        x:0;y:root.height-height

        MouseArea{
            anchors.fill: parent
            onClicked: {
                ball.x=0
                ball.y=root.height-ball.height
                ball.rotation=0
                anim.restart()
            }
        }
    }

    ParallelAnimation{
        id:anim

        SequentialAnimation{
            NumberAnimation{
                properties: "y"
                target: ball
                to:20
                duration: root.duration*0.4
                easing.type:Easing.OutCirc
            }

            NumberAnimation{
                properties: "y"
                target: ball
                to:root.height-ball.height
                duration: root.duration*0.6
                easing.type:Easing.OutBounce
            }
        }

        NumberAnimation{
            properties: "x"
            target: ball
            to:380
            duration: root.duration
        }

        RotationAnimation{
            properties: "rotation"
            target: ball
            to:720
            duration: root.duration
        }
    }
}

状态和转换

  • 状态定义了一组属性的更改,可以由特定条件触发。
  • 状态开关可以附加一个转换,该转换定义了这些更改对应的动画,或执行附加的行为。
  • 进入状态时也可以执行行为。
    例如,两个信号灯。stop用红色,go用绿色。两个灯光不应同时发光。
state: "stop" 

states: [ 
	State { 
		name: "stop" 
		PropertyChanges { target: light1; color: root.red }
		PropertyChanges { target: light2; color: root.black } 
	}, 
	State { 
		name: "go" 
		PropertyChanges { target: light1; color: root.black } 
		PropertyChanges { target: light2; color: root.green } 
	} 
] 

MouseArea { 
	anchors.fill: parent 
	onClicked: parent.state = (parent.state == "stop" ? "go" : "stop") 
} 

qml之动态元素类型_第7张图片
 现在能够成功地改变信号灯的状态。为了使UI更具吸引力,应该添加一些带有动画效果的过渡。状态改变可以触发转换。

transitions: [ 
	Transition { 
		from: "stop"; to: "go" 
		// from: "*"; to: "*" 
		ColorAnimation { target: light1; properties: "color"; duration: 2000 } 
		ColorAnimation { target: light2; properties: "color"; duration: 2000 } 
	} 
] 

rom: “"; to: "” 表示“从任何状态到任何其他状态”,是默认值。

代码

import QtQuick
import QtQuick.Window

Item {
    id: root
    width: 150;height:260
    property color black: 'black'
    property color red: 'red'
    property color green: 'green'

    Rectangle{
        anchors.fill: parent
        color:"#333333"
    }

    state: "stop"

    states: [
        State {
            name: "stop"
            PropertyChanges {target: light1;color:root.red;}
            PropertyChanges {target: light2;color:root.black;}
        },

        State {
            name: "go"
            PropertyChanges {target: light1;color:root.black;}
            PropertyChanges {target: light2;color:root.green;}
        }
    ]

    transitions: [
        Transition {
            from: "*";to: "*"
            ColorAnimation {
                target:light1;duration: 1000;properties: 'color'
            }
            ColorAnimation {
                target:light2;duration: 1000;properties: 'color'
            }
        }
    ]

    Rectangle{
        id:light1
        x:25;y:15
        width:100;height: width
        radius: width/2
        color:root.black
        border.color: Qt.lighter(color,1.1)
    }

    Rectangle{
        id:light2
        x:25;y:135
        width:100;height: width
        radius: width/2
        color:root.black
        border.color: Qt.lighter(color,1.1)
    }

    MouseArea{
        anchors.fill: root
        onClicked: {
            parent.state = ((parent.state == "stop")?"go":"stop")
        }
    }
}

完整代码链接

你可能感兴趣的:(qt,qml,c++,qt)