百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术流 > 正文

Qt Quick 动画入门篇(qt动画教程)

citgpt 2024-07-12 09:51 18 浏览 0 评论

简介

在使用 QML 进行界面开发时,我们的目标是创建一套流体界面,所谓流体界面指的是UI组件是动态变化的。举个例子,当界面上的组件需要变化时,如果视觉画布突然变化会导致用户的体验感比较差。而如果在状态的变化过程中,我们添加一些引导,把状态从初始慢慢变化到目标状态,让用户可以感受到这个变化的过程,那么用户的感官体验这一块就会大大提升了,而这也就是所谓的动态变化

这里需要引出几个重要的概念:State(状态)、Transition(过度)、Animation(动画)

Qt Quick 动画入门篇(qt动画教程)

State(状态):所有项目都有一个默认状态,用于定义对象和特性值的默认配置。可以通过向 states 属性添加状态项来定义新状态,以允许项在不同配置之间切换

Transition(过度):发生状态更改时要应用的动画

Animation(动画):随着时间的推移逐渐改变属性

具体请参考官方文档:Important Concepts in Qt Quick - States, Transitions and Animations

缓和曲线

通常动画中的变化是匀速的,如果开发者觉得太单调了,可以调节动画的变化速度曲线,即缓和曲线。我们通过动画的 easing 属性组来改变缓和曲线

type - 缓和曲线类型

amplitude - 幅度

period - 周期

overshoot - 过冲

bezierCurve - 贝塞尔

缓和曲线的类型如下所示:

动画类型

AnchorAnimation - 为锚定值的更改设置动画
领Qt学习资料→Qt开发(视频教程+文档+代码+项目实战)

Rectangle {
    id: myRect
    width: 100; height: 100
    color: "red"
    
    property int type: 1
    
    states: [
        State {
            name: "right"
            AnchorChanges { target: myRect; anchors.right: parent.right }
        },
        State {
            name: "bottom"
            AnchorChanges { target: myRect; anchors.bottom: parent.bottom }
        },
        State {
            name: "left"
            AnchorChanges { target: myRect; anchors.left: parent.left }
        },
        State {
            name: "top"
            AnchorChanges { target: myRect; anchors.top: parent.top }
        }
    ]
    
    transitions: Transition {
        AnchorAnimation { duration: 500 }
    }
    
    MouseArea {
        anchors.fill: parent
        onClicked: {
            let state = {
                1: "right",
                2: "bottom",
                3: "left",
                4: "top"
            }
            myRect.state = state[myRect.type]
            
            myRect.type++
            if ( myRect.type > 4 ) {
                myRect.type = 1
            }
        }
    }
}

ColorAnimation - 为颜色值的更改设置动画

Rectangle {
    id: myRect
    width: 100; height: 100
    color: "black"
    
    property int type: 1
    
    states: [
        State {
            name: "red"
            PropertyChanges { target: myRect; color: "red" }
        },
        State {
            name: "yellow"
            PropertyChanges { target: myRect; color: "yellow" }
        },
        State {
            name: "pink"
            PropertyChanges { target: myRect; color: "pink" }
        },
        State {
            name: "blue"
            PropertyChanges { target: myRect; color: "blue" }
        },
        State {
            name: "black"
            PropertyChanges { target: myRect; color: "black" }
        }
    ]
    
    transitions: Transition {
        ColorAnimation { duration: 500 }
    }
    
    MouseArea {
        anchors.fill: parent
        onClicked: {
            let state = {
                1: "red",
                2: "yellow",
                3: "pink",
                4: "blue",
                5: "black",
            }
            myRect.state = state[myRect.type]
            
            myRect.type++
            if ( myRect.type > 5 ) {
                myRect.type = 1
            }
        }
    }
}

NumberAnimation - 为 qreal 类型值的更改设置动画

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

    property int type: 1

    states: [
        State {
            name: "step1"
            PropertyChanges { target: myRect; x: 60; y: 60; width: 120; height: 120; rotation: 30 }
        },
        State {
            name: "step2"
            PropertyChanges { target: myRect; x: 60; y: 60; width: 120; height: 120; rotation: 60 }
        },
        State {
            name: "step3"
            PropertyChanges { target: myRect; x: 40; y: 40; width: 180; height: 180; rotation: 90 }
        },
        State {
            name: "step4"
            PropertyChanges { target: myRect; x: 100; y: 100; width: 50; height: 50; rotation: 45 }
        }
    ]

    transitions: Transition {
        NumberAnimation { duration: 500 }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            let state = {
                1: "step1",
                2: "step2",
                3: "step3",
                4: "step4"
            }
            myRect.state = state[myRect.type]

            myRect.type++
            if ( myRect.type > 4 ) {
                myRect.type = 1
            }
        }
    }
}

ParentAnimation - 为父类的更改设置动画

Rectangle {
    id: myRect
    width: 300; height: 100
    color: "black"

    property int type: 1

    Rectangle {
        id: redRect
        width: 100; height: 100
        color: "red"
    }

    Rectangle {
        id: blueRect
        x: 110
        width: 100; height: 100
        color: "blue"
    }

    Rectangle {
        id: yellowRect
        x: 220; y: 10
        width: 50; height: 50
        color: "yellow"

        states: [
            State {
                name: "red"
                ParentChange { target: yellowRect; parent: redRect; x: 10; y: 10 }
            },
            State {
                name: "blue"
                ParentChange { target: yellowRect; parent: blueRect; x: 10; y: 10 }
            },
            State {
                name: "black"
                ParentChange { target: yellowRect; parent: myRect; x: 220; y: 10 }
            }
        ]

        transitions: Transition {
            ParentAnimation {
                NumberAnimation { properties: "x,y"; duration: 500 }
            }
        }

        MouseArea {
            anchors.fill: parent
            onClicked: {
                let state = {
                    1: "red",
                    2: "blue",
                    3: "black"
                }
                yellowRect.state = state[myRect.type]

                myRect.type++
                if ( myRect.type > 3 ) {
                    myRect.type = 1
                }
            }
        }
    }
}

PathAnimation - 沿路径设置项目的动画

Rectangle {
    width: 400; height: 400

    PathInterpolator {
        id: motionPath

        path: Path {
            startX: 0; startY: 0

            PathCubic {
                x: 350; y: 350

                control1X: 350; control1Y: 0
                control2X: 0; control2Y: 350
            }
        }

        NumberAnimation on progress { id: animation; from: 0; to: 1; duration: 2000 }
    }

    Rectangle {
        x: motionPath.x; y: motionPath.y
        width: 50; height: 50
        rotation: motionPath.angle
        color: "green"
    }

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

PropertyAnimation - 为特性值的更改设置动画

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

    property bool location: true

    Behavior on x { PropertyAnimation {} }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            var x = location ? 50 : 0
            parent.x = x
            location = !location
        }
    }
}

RotationAnimation - 为旋转的更改设置动画

Item {
    width: 300; height: 300

    Rectangle {
        id: myRect
        width: 150; height: 100
        anchors.centerIn: parent
        color: "red"
        antialiasing: true

        property int type: 1

        states: [
            State {
                name: "state1"
                PropertyChanges { target: myRect; rotation: 45 }
            },
            State {
                name: "state2"
                PropertyChanges { target: myRect; rotation: 90 }
            },
            State {
                name: "state3"
                PropertyChanges { target: myRect; rotation: 180 }
            }
        ]

        transitions: Transition {
            RotationAnimation { duration: 1000; direction: RotationAnimation.Counterclockwise }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            let state = {
                1: "state1",
                2: "state2",
                3: "state3"
            }
            myRect.state = state[myRect.type]

            myRect.type++
            if ( myRect.type > 3 ) {
                myRect.type = 1
            }
        }
    }
}

Vector3dAnimation - 为 QVector3d 值的更改设置动画

Rectangle {
    id: myRect
    x: 50; y: 50
    width: 100; height: 100
    color: "red"

    transform: Rotation {
        angle: 45
        origin.x: 50; origin.y: 50
        axis: Qt.vector3d(0, 1, 0)

        SequentialAnimation on axis {
            id: animation
            running: false
            Vector3dAnimation { from: "1, 0, 0"; to: "0, 1, 0"; duration: 1000 }
            Vector3dAnimation { from: "0, 1, 0"; to: "0, 0, 1"; duration: 1000 }
            Vector3dAnimation { from: "0, 0, 1"; to: "1, 0, 1"; duration: 1000 }
            Vector3dAnimation { from: "1, 0, 1"; to: "1, 1, 0"; duration: 1000 }
            Vector3dAnimation { from: "1, 1, 0"; to: "1, 1, 1"; duration: 1000 }
            Vector3dAnimation { from: "1, 1, 1"; to: "1, 0, 1"; duration: 1000 }
            Vector3dAnimation { from: "1, 0, 1"; to: "0, 0, 1"; duration: 1000 }
            Vector3dAnimation { from: "0, 0, 1"; to: "0, 1, 0"; duration: 1000 }
            Vector3dAnimation { from: "0, 1, 0"; to: "1, 0, 0"; duration: 1000 }
        }
    }

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

组合动画

  • SequentialAnimation - 按顺序运行动画
Rectangle {
    id: rect
    width: 100; height: 100
    color: "red"

    SequentialAnimation {
        id: animation
        running: false
        NumberAnimation { target: rect; property: "x"; to: 100; duration: 500 }
        NumberAnimation { target: rect; property: "y"; to: 100; duration: 500 }
        NumberAnimation { target: rect; property: "x"; to: 0; duration: 500 }
        NumberAnimation { target: rect; property: "y"; to: 0; duration: 500 }
    }

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

ParallelAnimation - 并行运行动画

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

    ParallelAnimation {
        id: animation
        running: false
        NumberAnimation { target: rect; property: "x"; to: 100; duration: 1000 }
        NumberAnimation { target: rect; property: "y"; to: 100; duration: 1000 }
        NumberAnimation { target: rect; property: "width"; to: 200; duration: 1000 }
        NumberAnimation { target: rect; property: "height"; to: 200; duration: 1000 }
        NumberAnimation { target: rect; property: "rotation"; to: 90; duration: 1000 }
    }

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

行为动画

  • Behavior - 为特性更改指定默认动画
Rectangle {
    id: coloredRect
    width: 100; height: 100
    anchors.centerIn: parent
    color: "red"

    states: State {
        name: "GreenState"
        when: mouser.containsMouse

        PropertyChanges {
            target: coloredRect
            color: "green"
        }
    }

    Behavior on color {  ColorAnimation {} }

    MouseArea {
        id: mouser
        anchors.fill: parent
        hoverEnabled: true
    }
}

动画暂停

  • PauseAnimation - 在动画中引入暂停
Rectangle {
    id: rect
    width: 100; height: 100
    color: "red"

    SequentialAnimation {
        id: animation
        running: false
        NumberAnimation { target: rect; property: "x"; to: 100; duration: 500 }
        NumberAnimation { target: rect; property: "y"; to: 100; duration: 500 }
        PauseAnimation { duration: 1000 }
        NumberAnimation { target: rect; property: "x"; to: 0; duration: 500 }
        NumberAnimation { target: rect; property: "y"; to: 0; duration: 500 }
    }

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

弹簧动画

  • SpringAnimation - 模拟弹簧的振荡行为,使用适当的弹簧常数来控制加速度和阻尼,以控制效果消失的速度
Rectangle {
    id: rect
    width: 50; height: 50
    color: "red"

    Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
    Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            rect.x = mouse.x - rect.width/2
            rect.y = mouse.y - rect.height/2
        }
    }
}

属性跟踪动画

  • SmoothedAnimation - 允许特性平滑跟踪值
Item {
    Rectangle {
        width: 60; height: 60
        x: rect1.x - 5; y: rect1.y - 5
        color: "green"

        Behavior on x { SmoothedAnimation { velocity: 200; duration: 500 } }
        Behavior on y { SmoothedAnimation { velocity: 200; duration: 500 } }
    }

    Rectangle {
        id: rect1
        x: 5; y: 5
        width: 50; height: 50
        color: "red"
    }

    focus: true
    Keys.onRightPressed: rect1.x = rect1.x + 100
    Keys.onLeftPressed: rect1.x = rect1.x - 100
    Keys.onUpPressed: rect1.y = rect1.y - 100
    Keys.onDownPressed: rect1.y = rect1.y + 100
}

动画中运行脚本

  • ScriptAction - 在动画中运行脚本
Rectangle {
    id: rect
    width: 100; height: 100
    color: "red"

    SequentialAnimation {
        id: animation
        running: false
        NumberAnimation { target: rect; property: "x"; to: 100; duration: 500 }
        NumberAnimation { target: rect; property: "y"; to: 100; duration: 500 }
        ScriptAction { script: doSomething() }
        NumberAnimation { target: rect; property: "x"; to: 0; duration: 500 }
        NumberAnimation { target: rect; property: "y"; to: 0; duration: 500 }
        ScriptAction { script: doStateStuff() }
    }

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

    function doSomething() {
        rect.color = "blue"
        rect.width = 120
        rect.height = 120
    }

    function doStateStuff() {
        rect.color = "red"
        rect.width = 100
        rect.height = 100
    }
}

相关推荐

Linux系统中的sudo命令、APT软件包管理器以及Java开发工具包JDK

sudo命令详解:sudo命令允许用户以root权限执行命令,类似于Windows系统中的“以管理员身份运行”。这在需要系统级权限操作时非常有用。更多信息请参考:https://do...

js中arguments详解

一、简介了解arguments这个对象之前先来认识一下javascript的一些功能:其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数...

firewall-cmd 常用命令

目录firewalldzone说明firewallzone内容说明firewall-cmd常用参数firewall-cmd常用命令常用命令 回到顶部firewalldzone...

epel-release 是什么

EPEL-release(ExtraPackagesforEnterpriseLinux)是一个软件仓库,它为企业级Linux发行版(如CentOS、RHEL等)提供额外的软件包。以下是关于E...

FullGC详解  什么是 JVM 的 GC
FullGC详解 什么是 JVM 的 GC

前言:背景:一、什么是JVM的GC?JVM(JavaVirtualMachine)。JVM是Java程序的虚拟机,是一种实现Java语言的解释器。 它提供了一种独立于操作系统的运行环境,使得Java程序在任...

2024-10-26 08:50 citgpt

使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
跨域(CrossOrigin)

1.介绍  1)跨域问题:跨域问题是在网络中,当一个网络的运行脚本(通常时JavaScript)试图访问另一个网络的资源时,如果这两个网络的端口、协议和域名不一致时就会出现跨域问题。    通俗讲...

微服务架构和分布式架构的区别

1、含义不同微服务架构:微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并...

深入理解与应用CSS clip-path 属性
深入理解与应用CSS clip-path 属性

clip-pathclip-path是什么clip-path 是一个CSS属性,允许开发者创建一个剪切区域,从而决定元素的哪些部分可见,哪些部分会被隐藏。通过定义这个剪切路径(clippingpath),您可以创造出非矩形的裁剪...

2024-10-25 11:51 citgpt

HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
Redis和Memcached的区别详解
Redis和Memcached的区别详解

Redis的作者SalvatoreSanfilippo曾经对这两种基于内存的数据存储系统进行过比较:1.Redis支持服务器端的数据操作:Redis相比Memcached来说,拥有更多的数据结构和并支持更丰...

2024-10-25 11:51 citgpt

Request.ServerVariables 大全

Request.ServerVariables("Url")返回服务器地址Request.ServerVariables("Path_Info")客户端提供的路...

python操作Kafka

目录一、python操作kafka1.python使用kafka生产者2.python使用kafka消费者3.使用docker中的kafka二、python操作kafka细...

Runtime.getRuntime().exec详解

Runtime.getRuntime().exec详解概述Runtime.getRuntime().exec用于调用外部可执行程序或系统命令,并重定向外部程序的标准输入、标准输出和标准错误到缓冲池。...

promise.all详解 promise.all是干什么的
promise.all详解 promise.all是干什么的

promise.all详解promise.all中所有的请求成功了,走.then(),在.then()中能得到一个数组,数组中是每个请求resolve抛出的结果。promise.all中只要有一个失败了,走.catch(),在.catch(...

2024-10-24 16:21 citgpt

取消回复欢迎 发表评论: