前言

使用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改为-height,opacity改为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。注意这里的PropertyAnimation的from和to属性是不需要定义的,因为这些值已经提供了,分别是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
}
}
}
}

因为动画没有绑定到一个特定的对象或者属性,所以必须指定target和property(或者targets和properties)属性的值。而且还需要使用to属性来指定新的x和y的值。

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()函数来明确地运行它。因为动画没有绑定到一个特殊得对象或属性上,所以必须定义target和property(或者targets和properties)属性的值。也需要用to属性来指定新的x和y值。对于动画在不是一对一对象属性进行动画而且动画需要明确开始和停止的情况下是非常有用的。

动画元素

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

PropertyAnimation是用来为属性提供动画的最基本的动画元素,可以用来为real、int、color、rect、point、size和vector3d等属性设置动画,被NumberAnimation、colorAnimation、RotationAnimation和Vector3dAnimation等元素继承。NumberAnimation对real和int属性提供了更高效的实现;Vector3dAnimation对vector3d属性提供了更高效的支持;而ColorAnimation和RotationAnimation分别对color和rotation属性变化动画提供了特定的属性支持。

1. ColorAnimation允许颜色值设置from和to属性。

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:; 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动画的更多相关文章

  1. Qt Widgets、QML、Qt Quick的区别

    Qt Widgets.QML.Qt Quick的区别 简述 看了之前关于 QML 的一些介绍,很多人难免会有一些疑惑: Q1:QML 和 Qt Quick 之间有什么区别? Q2:QtQuick 1. ...

  2. Qt Quick 之 QML 与 C++ 混合编程具体解释

    Qt Quick 技术的引入.使得你能够高速构建 UI ,具有动画.各种绚丽效果的 UI 都不在话下.但它不是万能的.也有非常多局限性,原来 Qt 的一些技术,比方低阶的网络编程如 QTcpSocke ...

  3. qt quick中qml编程语言

    Qt QML 入门 — 使用C++定义QML类型 发表于 2013 年 3 月 11 日   注册C++类 注册可实例化的类型 注册不实例化的QML类型 附带属性 注册C++类 注册可实例化的类型 如 ...

  4. QML动画概述(几十篇相关博客)

    QML提供了丰富的动画元素,说起动画,无非是给UI增光添彩罢了.在QML中,动画常常与State和Transition联系在一起,这几个概念(下面的例子中都用到了)都比较简单,相关介绍可查看Qt官方文 ...

  5. qt程序启动播放动画

    qt程序启动播放动画 编辑删除转载 2016-01-20 10:23:11 标签:qt启动动画 1.播放动画 QAxWidget *flash = , ); //QAxWidget使用的是Active ...

  6. 【Qt】Qt Quick 之 QML 与 C++ 混合编程详解

    Qt Quick 之 QML 与 C++ 混合编程详解 - CSDN博客   专栏:Qt Quick简明教程 - CSDN博客   .

  7. Qt Quick 和qml介绍

    很多人不了解Qt Quick和Qml,还有很多人对其存在偏见.这篇文章就是来向这些有困惑的人介绍一下其是什么,有什么特点. 首先,这两个是一个东西吗? 答案:是的.但是,具体来说,Qt Quick是框 ...

  8. 【基础】Qt SCXML Calculator QML Example

    Qt SCXML Calculator QML Example 这个系统自带的例子原本主要是用来说明SCXML机制的,但是由于计算器的经典和简洁,我认为用来练习QML非常合适,原本的例子还有一些问题, ...

  9. Qt 5.7 > QML

    本文档翻译自Qt官方文档: http://doc.qt.io/qt-5/qtqml-index.html Qt QML Qt QML模块使用QML语言为开发应用与库提供一个框架.它定义并实现了语言与引 ...

随机推荐

  1. Django 应用程序 + 模型 + 基本数据访问

    如果你只是建造一个简单的web站点,那么可能你只需要一个app就可以了.如果是复杂的象 电子商务之类的Web站点,你可能需要把这些功能划分成不同的app,以便以后重用. 确实,你还可以不用创建app, ...

  2. 如何运行一个Vue项目

    一开始很多刚入手vue.js的人,会扒GitHub上的开源项目,但是发现不知如何运行GitHub上的开源项目,很尴尬.通过查阅网上教程,成功搭建好项目环境,同时对前段工程化有了朦朦胧胧的认知,因此将环 ...

  3. python-作用域解析

    局部作用域和全局作用域:局部作用域不能修改全局作用域的变量 count = 10 def outer(): #global count 局部变量改成全局变量,global声明一下即可.就可以修改了. ...

  4. Flutter工程无法找到Android真机或Android模拟器

    之前的Flutter的工程链接真机还好好的 结果电脑抽抽了过了个年就连不到真机了 一点run就提示 No connected devices found; please connect a devic ...

  5. 菜鸟脱壳之脱壳的基础知识(六)——手动查找IAT和修复Dump的程序

    前面讲了如何寻找OEP和脱壳,有的时候,Dump出来的时候不能正常运行,是因为还有一个输入表没有进行处理,一些加密壳会在IAT加密上面大做文章,用HOOK - API的外壳地址来代替真是的IAT的地址 ...

  6. [转]关于Megatops BinCalc RPN计算器的说明

    最近收到几个好心人发来的邮件,指出我的BinCalc存在低级BUG,即1+1算出来不等于2--鉴于存在这种误解的人之多,俺不得不爬出来澄清一下--我的Megatops BinCalc当中的计算器是RP ...

  7. vmware12启动centos6.8报错ACPI:memory_hp:Memory online failed

    报错信息 打开后出现黑屏上只显示 ACPI:memory_hp:Memory online failed for 0x10000000 - 0x80000000 BUG: soft lockup - ...

  8. python 两个 list 获取交集,并集,差集的函数

    1. 获取两个 list 的交集 a = [1, 2, 3, 4] b = [1, 2, 5] print(list(set(a).intersection(set(b)))) 2. 获取两个 lis ...

  9. 【转】C# 中Linq查询所有上级节点或所有下级节点

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net ...

  10. 版本控制,django缓存,跨域问题解决

    复习 分页: 1. 简单分页 2. 偏移分页 3. 加密分页 解析器:客户处理前端提交来的数据 urlencode: body体中的数据格式: key=value& formdata编码:为区 ...