include:
Declarative markup language :QML
add QML into Qt apps by the c++ API QtDeclarative
QML是一种声明性语言:
定义应用的外观和引用的行为;
QML界面程序有一组树型结构的容器组合而成
QML语法-import
import指明你要引入的Qt模块版本
仅仅导入对应版本的Qt所支持的特性
保证整个代码的行为不会因为Qt的版本不同而发生改变
QML语法-注释
和c一样的注释语法
QML语法-Elements
声明你要使用的元素:
在文件中声明一个根元素
每个元素的内容需要在大括号里
QT模块中包含了一些默认的元素
例子:
import Qt 4.7
Rectangle {
width:350
height:2*100
color:"lightblue"
}
标准QML元素
1.QML ITEMS
Item,Rectangle ,Image,Text,MouseArea,WebView,ListView。。。
其中一些元素可以作为其他元素(children)的容器
所有用于创建UI的元素都是从item继承而来。
2.QML declarative elements
还有一些 元素用来描述应用程序行为:
State,PropertyAnimation,Transition,Timer,Connection
3.基本属性
x,y,z position
width and height
anchors ......
元素包含了属性,每一个属性都包括了名称和值,一行可以用“;”隔开声明多个属性
属性的例子:
Standard properties 标准属性可以直接用值初始化:
Text{
text:"Hello world"
height:50
}
Grouped Properties 分组属性将相关的属性放在一起:
Text{
font.family:"Helvetica"
font.pixelSize:24
}
Identity property标识属性用于唯一的表示一个元素:
Text{
id:label
text:"Hello world'
}
属性-颜色:
元素的颜色定义可以有如下方法:
用一个字符串来表示:svg颜色名字,“red“,”green“,”blue“
用一个字符串来表示颜色的组成:r,g,b:#rrggbb;
使用内建函数(r,g,b,aphla):Qt.rgba(0,0.5,0,1)
使用opacity属性:从0.0到1.0
字符元素
显示字符串
宽度和高度由字体和文本所决定的
也可以从超级链接获取
或者使用HTML标签:"Qt Quick"
可编辑的字符串TextInupt:不是QLineEdit
Image
Image{
width:parent.width
source:"justiina.jpg"
}
source指定了图片的相对路径
高度和宽度默认是从图片文件获得,
如果直接设置,根据设置的值来缩放图片,
属性fillMode来设置缩放时的长度比例,
设置scale缩放图片,设置rotate旋转图片(度是旋转的单位)
旋转式围绕图片的中心,
通过transformOrigin属性来设置旋转的围绕点。
布局管理器
硬编码图元的位置绝对不是一个好方法
提供UI的可测量性很困难
维护困难
QML提供很多不同种类的布局工具代替硬编码的方法
anchor部件管理:只能在兄弟元素之间或者父子之间使用anchor
布局器:Grid,Row,Column
每个QML元素都可以认为有6个方位和4个边缘
item可以重叠。可以显示在parent之外
网格布局
Grid{
colmns:(列数)
spacing:
.......
}
将孩子items以表格的形式展现
纵向布局:row行
Row{
spacing:
......
}
横向布局:column列
Column{
spacing:2
......
}
联合布局
Grid,Row ,Column可以嵌套使用
===================================================
用户交互
用户与QML交互
QML中要出理时间,需要定义一个槽:
这个槽仅仅只是一个属性property
这个属性的名字与事件的类型是相关的
Mouse areas
用于定义屏幕的某区域接收鼠标事件
位置和大小与普通items是一样使用的
可以对Mouse Area使用anchors
两种方法处理鼠标输入:
处理信号
动态属性绑定
定义响应信号的槽(信号)
onPressed和onReleased,onClicked,onDoubleClicked,onPressAndHold,
默认情况,只接受左键
通过的设置acceptedButtons来改变接受的鼠标按键
• 信号携带类型为 MouseEvent 的参数 mouse
Rectangle {
width: 100; height: 100; color: "green"
MouseArea {
anchors.fill: parent
// See Qt::MouseButtons for a list of available buttons
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (mouse.button == Qt.RightButton)
parent.color = 'blue';
else
parent.color = 'red';
}
}
}
拖拽元素
通过设置MouseArea的属性drag,可以让某个元素可以被拖拽
MouseArea {
anchors.fill: parent
drag.target: pic
drag.axis: "XAxis"
drag.minimumX: 0
drag.maximumX: opacitytest.width-pic.width
}
鼠标旋停与属性(绑定属性)
color: mouse_area.containsMouse ? "green" : "white"
MouseArea {
id: mouse_area
anchors.fill: parent
hoverEnabled: true//设置鼠标旋停属性true
}
鼠标区域只会相应acceptedButtons所定义的鼠标按键
槽不会接受到其它的鼠标按键
只有指定的鼠标按键才会被响应
多个鼠标被按下是pressedButtons属性会记录所有的按键
如果由acceptedButtons指定的按钮被按下,没有被指定的按钮也会被记录
当hoverEnabled为false的时候
当鼠标按下时containMouse属性为true
---------------------------------------------------------------------------------
键盘输入
1.接受文本输入
2.元素之间导航
改变元素的焦点
3.按键输入
TextInput{
text:qsTr("")
}
改变 焦点:
只有一个TextInput,焦点自动在TextInput上
如果有多个,通过鼠标点击改变焦点
通过设置focus属性来改变焦点
焦点导航:
通过定义KeyNavigation.tab:xx //按下tab焦点移到xx上//backtab为按下shitf+tab
键盘按键输入
• 所有可视的元素都可以通过 Keys 的attached属性支持键盘事件的处理
• 支持非常多的键盘事件
• 通用事件: onPressed, onReleased
• 专用事件: onReturnPressed, onSelectPressed,
onVolumeUpPressed, ...
• 他们都有个类型为 KeyEvent 的 参数 event
• 处理通用信号时
• 需要显示的告知事件被处理了
event.accepted = true;
• 否则,这个事件将会传递
• 专用事件默认就将事件处理了
import Qt 4.7
Rectangle {
width: 400; height: 400; color: "black"
Image {
id: rocket
x: 150; y: 150
source: "../images/rocket.svg"
transformOrigin: Item.Center
}
Keys.onLeftPressed:
rocket.rotation = (rocket.rotation - 10) % 360
Keys.onRightPressed:
rocket.rotation = (rocket.rotation + 10) % 360
focus: true
}
------------------------------------------------------------------------------------------------
状态/过度和动画
通过设置状态和过渡来定义用户界面的行为
提供一种方法来描述用户界面
有效的组织应用程序的逻辑
可以帮助我们判断是否所有的功能都被覆盖到了
可以应用动画和视觉效果来扩展过渡变化
State状态
状态用于管理有id的元素
它是由多个State元素构成的
每个元素都可以定义多个不同状态
使用state属性定义状态列表
当前的状态由state属性指定
当元素进入某个状态时,状态所对应的属性将被设置
我们可以
修改anchors对齐方式
修改item的parent
执行一段javascript代码
state例子:
importQtQuick1.1
Item{
id:item
width:480;height:480
TextInput{
id:text1
width:parent.width
x:20;y:20
text:"hi"
}
states:[
State{
name:"display"
PropertyChanges{target:text1;text:"display"}
},
State{
name:"shut"
PropertyChanges{
target:text1;text:"shut"
}
}
]
Grid{
columns:2
spacing:2
anchors.centerIn:parent
Rectangle{
id:rec1
width:50
height:50
color:focus?"pink":"black"
focus:true
}
Rectangle{
id:rec2
width:50;height:50
color:focus?"pink":"green"
}
Rectangle{
id:rec3
width:50;height:50
color:focus?"pink":"grey"
}
Rectangle{
id:rec4
width:50;height:50
color:focus?"pink":"red"
}
}
Keys.onPressed:{
item.state=="display"?item.state="shut":item.state="display"
if(event.key==Qt.Key_Up)
{
event.accepted=true;
switch(true)
{
caserec1.focus:rec3.forceActiveFocus();break;
caserec2.focus:rec4.forceActiveFocus();break;
caserec3.focus:rec1.forceActiveFocus();break;
caserec4.focus:rec2.forceActiveFocus();break;
}
}
if(event.key==Qt.Key_Down)
{
event.accepted=true;
switch(true)
{
caserec1.focus:rec3.forceActiveFocus();break;
caserec2.focus:rec4.forceActiveFocus();break;
caserec3.focus:rec1.forceActiveFocus();break;
caserec4.focus:rec2.forceActiveFocus();break;
}
}
if(event.key==Qt.Key_Left)
{
event.accepted=true;
switch(true)
{
caserec1.focus:rec2.forceActiveFocus();break;
caserec2.focus:rec1.forceActiveFocus();break;
caserec3.focus:rec4.forceActiveFocus();break;
caserec4.focus:rec3.forceActiveFocus();break;
}
}
if(event.key==Qt.Key_Right)
{
event.accepted=true;
switch(true)
{
caserec1.focus:rec2.forceActiveFocus();break;
caserec2.focus:rec1.forceActiveFocus();break;
caserec3.focus:rec4.forceActiveFocus();break;
caserec4.focus:rec3.forceActiveFocus();break;
}
}
}
}
-----------------------------------------------
状态条件
使用状态的另一种方法:
让State决定何时被激活
使用条件判断来决定是否激活一个state
使用when属性
用表达式来判断条件,并返回true或者false
state list中只能有一个state是被激活的:确保一个时间只有一个条件为真
Rectangle {
width: 250; height: 50; color: "#ccffcc"
TextInput {
id: text_field
text: "Enter text..."
...
}
Image {
id: clear_button
source: "../images/clear.svg"
...
MouseArea {
anchors.fill: parent
onClicked: text_field.text = ""
}
}
}
states: [
State {
name: "with text"
when: text_field.text != ""
PropertyChanges { target: clear_button;
opacity: 1.0 }
},
State {
name: "without text"
when: text_field.text == ""
PropertyChanges { target: clear_button;
opacity: 0.25 }
PropertyChanges { target: text_field;
focus: true }
}
]
------------------------------------------------------------------------------
过渡transition元素
Transition元素用于为状态之间的切换提供动画支持
过渡只能被状态切换激活
过渡中的动画可以以串行或者并行的方式执行
通过设置to和from属性,我们可以指定与特定状态绑定的动画
他们默认被设置为“*”,i.e.任意状态//使用*设置只要有状态改变,过渡就会被执行
过渡可以被设置为reversible(默认false)
当条件满足是,自动切换到以前的状态1-》当条件满足是2-》1
----------------------------------------------------------------------------------
可逆过渡reversible
状态如果使用when属性,就可以使用可逆过渡
当两个过渡应用到相同的属性是,可以实现可逆过渡
-------------------------------------------------------------------------------------------
动画
可以对元素的属性变化加入动画
Types:real,int,color,rect,point,size
有三种使用动画的方法
基本的属性动画,过渡,属性行为
动画可以分组:串行或并行的执行
SequentialAnimation,ParallelAnimation,PauseAnimation
预定义的easing curve
OutQuad,InElastic,OutBounce;.....
了解更详细的信息,查看PropertyAnimation文档
使用属性动画,我们使用
ProperyAnimation,NumberAnimation,or ColorAnimation
他们有一个公共的基类:Animation
对于属性行为,使用Behavior
对于过渡,使用Transition
动画实例:
Rectangle {
// Example of a drop-and-bounce effect on an image
id: rect
width: 120; height: 200;
Image {
id: img
source: "qt-logo.png"
x: 60-img.width/2
y: 0
}
}
SequentialAnimation on y {
running: true; loops: Animation.Infinite
NumberAnimation {
to: 200-img.height; easing.type: "OutBounce"; duration: 2000
}
PauseAnimation { duration: 1000 }
NumberAnimation {
to: 0; easing.type: "OutQuad"; duration: 1000
}
}
===============================================
行为属性:behavior
设置一个默认的动画在属性发生改变的时候执行:无论什么造成的属性改变都会执行
Rectangle {
id: redRect
color: "red"
width: 100; height: 100
x: ...
Behavior on x {
NumberAnimation { duration: 300; easing.type: "InOutQuad" }//从x0出现动画移动到x1
}
}
=========================
使用状态和过渡
避免定义过于复杂的状态机
不要用一个状态机来管理所有的UI部分
针对不同的控件使用独立的状态机
然后通过状态把控件的状态联系起来
------------------------------------------------------------------------
状态总结
使用状态来管理其他元素的属性;
定义状态使用元素的state属性
每个状态都必须有独立的名字
给元素设置一个id是很有用的
使用PropertyChanges来修改元素的属性
元素的state属性,保存了当前的状态
可以使用javascript来修改他的值
也可以使用when属性来设1置状态成立条件
---------------------------------------------------------------------------
过渡总结
过渡用来描述状态之间的切换过程
使用transitions属性来定义元素的过渡
过渡需要描述始末的两个状态(from:to),可以使用通配符*来表示所有状态
过渡是可逆的
相当于把from和to属性的值交换reversible:true
=================================================
计时器
计时器使用Timer元素表示的
只提供了一个简单的信号:onTriggered
可以是单次或者重复的计时器
Timer {
interval: 500;
running: true;
repeat: true
onTriggered: time.text = Date().toString()
}
Text {
id: time
}
=================================================
QML核心特征
简单的qml代码包含了QML元素
.qml后缀,编码方式UTF-8
总是以至少一个import语句开始
nothing is imported by default
并没有包含什么代码,仅仅知识为在运行是解释器寻找元素的定义!
定义唯一的顶层QML组件
Self-contained
再执行之前并没有预处理机制
在运行时解释执行!
组件是由QML基本元素构成的
创建自己的组建是非常容易的
组建的名字要以大写字母开始("MyButton.qml")
例子:模块编写
// Definition in MyButton.qml
// (Notice the capital ”M” in the file name above)
import Qt 4.7
Rectangle {
property alias text: textElement.text
width: 100; height: 30
source: "images/toolbutton.sci"
Text {
id: textElement
anchors.centerIn: parent
font.pointSize: 20
style: Text.Raised; color: "white"
}
}
// Usage e.g. in main.qml
// (Just an entry point file, thus lower-case ”m”)
import Qt 4.7
Rectangle {
MyButton {//is the same name as MyButton.qml
anchors.horizontalCenter: parent.horizontalCenter
text: "Orange"
}
...}
--------------------------------------------------------------------------------------
一个组件可以声明为内联组件
用关键字Component声明
可以使用parent的属性或者导入列表中的元素
需要多次在一个QML文件中根据需要被使用(从逻辑上这个组建也只属于这个QML文件)
Inline QML Component内联模块
// In MyComponent.qml
import Qt 4.6
Item {
Component { // The inline component
id: redSquare
Rectangle {
color: "red"
width: 50
height: 50
}
}
Loader { sourceComponent: redSquare }
Loader { sourceComponent: redSquare; x: 70 }
}
---------------------------------------------------------------------------------
QML模块
多个QML组件可以组合到一个QML模块中
最简单的方法是创建一个子文件夹,然后把所有控件放置进去
这些控件可以使用import语句导入到QML的文件中:
import“path_to_mymodule"//path_to_mymodule =文件名
也可以使用命令导入
QML组件也可以在工程外的文件定义
import com.nokia.SomeStuff 1.0// com/nokia/SomeStuff
或者使用qmldir的文件描述import内容
----------------------------------------------------------------------------------
渐进载入
当QML的某个对象引用网络资源的时候,那么它将会提供整个加载过程的进度状态
======================================================================
数据模型和视图
QML使用了与Qt中Model-View类似的结构
模型类提供了数据
模型可以是QML的简单数据,或者复杂的C++数据
QML:ListModel,XmlListModel,VisualItemModel
C++:QAbstractIemModel,QStringList,QList
视图显示模型提供的数据
ListView,GridView,PathView,Repeate(all QML)
都自动支持滚动
代理为视图创建模型中的数据的实例
Hightlight控件用来高亮视图里面的选中item
我们需要来什么?它们是什么?
Model:你的数据
Delegate:(代表)一个描述model中每条数据的显示方式的控件 ,如果是visualItemModel则不需要
View:可视的元素,使用delegate来显示model中的数据
View分为:ListView/GridView/PathView
=================================================
QML高级特性
扩展QML的类型
QML很多核心类型和元素由C++实现,然而用纯QML对这些类型进行扩展也是可能的。
可以:
添加新的属性properties/
添加新的信号signals/
添加新的方法methods/
定义新的QML控件/
添加新属性:property style name:property
新的属性也可以是现有的属性别名:property alias name :property(定义新组件是有用)
只有在控件完全实例化的时候才能使用别名,模块化
添加新的信号:signal xxx()
添加新的方法:
使用JavaScript实现
在QML端可以直接使用,在C++端是槽函数,使用没有类型的参数,(在c++端它的类型为QVariant)
例子:
Item{
id:myItem
function name( parm){
}
}
//use the method
myItem.say("HelloWorld");
==================================================================
QML全局对象
QML提供了全局的JavaScript对象Qt
在QML的任意部分都可以使用
提供了大量的函数
创建QML类型:Qt.rect(...),Qt.rgba(...),Qt.point(...)
做一些其他的常用操作:
Qt.playSound(...),Qt.openUrlExternally(...),Qt.md5(...)
也提供了动态QML对象的创建,AJAX和本地数据访问的接口
----------------------------------------------------------------
在QML中使用JaveScript
JaveScript不能用于为全局对象添加新的成员
在声明变量时,可以省var关键字
两种方法使用JavaScript
lnline JaveScript
独立的javascript文件
-------------------------------
lnline JavaScript
Item{
function factorial(a){
a=parseInt(a);
if(a<=0)
return 1;
else
return a*factorial(a-1);
}
MouseArea{
anchors.fill:parent
onClicked:console.log(factorial(10))
}
}
--------------------------
独立JavaScript文件
import “factorial.js” as Name// 调用的方法:Name.xx()
-----------------------------------------------------------
QML域
当创建了QML组建实例,QML自动为他生成一个于用于:JavaScript的执行和属性的绑定
当系统解析某个引用的时候,作用域的搜索是按照特定的顺序:
JavaScript ariables,functions,and property bindings
attached properties or enumerations
Qt Quick=Qt User Interface Creation Kit
include:
Declarative markup language :QML
add QML into Qt apps by the c++ API QtDeclarative
QML是一种声明性语言:
定义应用的外观和引用的行为;
QML界面程序有一组树型结构的容器组合而成
QML语法-import
import指明你要引入的Qt模块版本
仅仅导入对应版本的Qt所支持的特性
保证整个代码的行为不会因为Qt的版本不同而发生改变
QML语法-注释
和c一样的注释语法
QML语法-Elements
声明你要使用的元素:
在文件中声明一个根元素
每个元素的内容需要在大括号里
QT模块中包含了一些默认的元素
例子:
import Qt 4.7
Rectangle {
width:350
height:2*100
color:"lightblue"
}
标准QML元素
1.QML ITEMS
Item,Rectangle ,Image,Text,MouseArea,WebView,ListView。。。
其中一些元素可以作为其他元素(children)的容器
所有用于创建UI的元素都是从item继承而来。
2.QML declarative elements
还有一些 元素用来描述应用程序行为:
State,PropertyAnimation,Transition,Timer,Connection
3.基本属性
x,y,z position
width and height
anchors ......
元素包含了属性,每一个属性都包括了名称和值,一行可以用“;”隔开声明多个属性
属性的例子:
Standard properties 标准属性可以直接用值初始化:
Text{
text:"Hello world"
height:50
}
Grouped Properties 分组属性将相关的属性放在一起:
Text{
font.family:"Helvetica"
font.pixelSize:24
}
Identity property标识属性用于唯一的表示一个元素:
Text{
id:label
text:"Hello world'
}
属性-颜色:
元素的颜色定义可以有如下方法:
用一个字符串来表示:svg颜色名字,“red“,”green“,”blue“
用一个字符串来表示颜色的组成:r,g,b:#rrggbb;
使用内建函数(r,g,b,aphla):Qt.rgba(0,0.5,0,1)
使用opacity属性:从0.0到1.0
字符元素
显示字符串
宽度和高度由字体和文本所决定的
也可以从超级链接获取
或者使用HTML标签:"Qt Quick"
可编辑的字符串TextInupt:不是QLineEdit
Image
Image{
width:parent.width
source:"justiina.jpg"
}
source指定了图片的相对路径
高度和宽度默认是从图片文件获得,
如果直接设置,根据设置的值来缩放图片,
属性fillMode来设置缩放时的长度比例,
设置scale缩放图片,设置rotate旋转图片(度是旋转的单位)
旋转式围绕图片的中心,
通过transformOrigin属性来设置旋转的围绕点。
布局管理器
硬编码图元的位置绝对不是一个好方法
提供UI的可测量性很困难
维护困难
QML提供很多不同种类的布局工具代替硬编码的方法
anchor部件管理:只能在兄弟元素之间或者父子之间使用anchor
布局器:Grid,Row,Column
每个QML元素都可以认为有6个方位和4个边缘
item可以重叠。可以显示在parent之外
网格布局
Grid{
colmns:(列数)
spacing:
.......
}
将孩子items以表格的形式展现
纵向布局:row行
Row{
spacing:
......
}
横向布局:column列
Column{
spacing:2
......
}
联合布局
Grid,Row ,Column可以嵌套使用
===================================================
用户交互
用户与QML交互
QML中要出理时间,需要定义一个槽:
这个槽仅仅只是一个属性property
这个属性的名字与事件的类型是相关的
Mouse areas
用于定义屏幕的某区域接收鼠标事件
位置和大小与普通items是一样使用的
可以对Mouse Area使用anchors
两种方法处理鼠标输入:
处理信号
动态属性绑定
定义响应信号的槽(信号)
onPressed和onReleased,onClicked,onDoubleClicked,onPressAndHold,
默认情况,只接受左键
通过的设置acceptedButtons来改变接受的鼠标按键
• 信号携带类型为 MouseEvent 的参数 mouse
Rectangle {
width: 100; height: 100; color: "green"
MouseArea {
anchors.fill: parent
// See Qt::MouseButtons for a list of available buttons
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (mouse.button == Qt.RightButton)
parent.color = 'blue';
else
parent.color = 'red';
}
}
}
拖拽元素
通过设置MouseArea的属性drag,可以让某个元素可以被拖拽
MouseArea {
anchors.fill: parent
drag.target: pic
drag.axis: "XAxis"
drag.minimumX: 0
drag.maximumX: opacitytest.width-pic.width
}
鼠标旋停与属性(绑定属性)
color: mouse_area.containsMouse ? "green" : "white"
MouseArea {
id: mouse_area
anchors.fill: parent
hoverEnabled: true//设置鼠标旋停属性true
}
鼠标区域只会相应acceptedButtons所定义的鼠标按键
槽不会接受到其它的鼠标按键
只有指定的鼠标按键才会被响应
多个鼠标被按下是pressedButtons属性会记录所有的按键
如果由acceptedButtons指定的按钮被按下,没有被指定的按钮也会被记录
当hoverEnabled为false的时候
当鼠标按下时containMouse属性为true
---------------------------------------------------------------------------------
键盘输入
1.接受文本输入
2.元素之间导航
改变元素的焦点
3.按键输入
TextInput{
text:qsTr("")
}
改变 焦点:
只有一个TextInput,焦点自动在TextInput上
如果有多个,通过鼠标点击改变焦点
通过设置focus属性来改变焦点
焦点导航:
通过定义KeyNavigation.tab:xx //按下tab焦点移到xx上//backtab为按下shitf+tab
键盘按键输入
• 所有可视的元素都可以通过 Keys 的attached属性支持键盘事件的处理
• 支持非常多的键盘事件
• 通用事件: onPressed, onReleased
• 专用事件: onReturnPressed, onSelectPressed,
onVolumeUpPressed, ...
• 他们都有个类型为 KeyEvent 的 参数 event
• 处理通用信号时
• 需要显示的告知事件被处理了
event.accepted = true;
• 否则,这个事件将会传递
• 专用事件默认就将事件处理了
import Qt 4.7
Rectangle {
width: 400; height: 400; color: "black"
Image {
id: rocket
x: 150; y: 150
source: "../images/rocket.svg"
transformOrigin: Item.Center
}
Keys.onLeftPressed:
rocket.rotation = (rocket.rotation - 10) % 360
Keys.onRightPressed:
rocket.rotation = (rocket.rotation + 10) % 360
focus: true
}
------------------------------------------------------------------------------------------------
状态/过度和动画
通过设置状态和过渡来定义用户界面的行为
提供一种方法来描述用户界面
有效的组织应用程序的逻辑
可以帮助我们判断是否所有的功能都被覆盖到了
可以应用动画和视觉效果来扩展过渡变化
State状态
状态用于管理有id的元素
它是由多个State元素构成的
每个元素都可以定义多个不同状态
使用state属性定义状态列表
当前的状态由state属性指定
当元素进入某个状态时,状态所对应的属性将被设置
我们可以
修改anchors对齐方式
修改item的parent
执行一段javascript代码
state例子:
importQtQuick1.1
Item{
id:item
width:480;height:480
TextInput{
id:text1
width:parent.width
x:20;y:20
text:"hi"
}
states:[
State{
name:"display"
PropertyChanges{target:text1;text:"display"}
},
State{
name:"shut"
PropertyChanges{
target:text1;text:"shut"
}
}
]
Grid{
columns:2
spacing:2
anchors.centerIn:parent
Rectangle{
id:rec1
width:50
height:50
color:focus?"pink":"black"
focus:true
}
Rectangle{
id:rec2
width:50;height:50
color:focus?"pink":"green"
}
Rectangle{
id:rec3
width:50;height:50
color:focus?"pink":"grey"
}
Rectangle{
id:rec4
width:50;height:50
color:focus?"pink":"red"
}
}
Keys.onPressed:{
item.state=="display"?item.state="shut":item.state="display"
if(event.key==Qt.Key_Up)
{
event.accepted=true;
switch(true)
{
caserec1.focus:rec3.forceActiveFocus();break;
caserec2.focus:rec4.forceActiveFocus();break;
caserec3.focus:rec1.forceActiveFocus();break;
caserec4.focus:rec2.forceActiveFocus();break;
}
}
if(event.key==Qt.Key_Down)
{
event.accepted=true;
switch(true)
{
caserec1.focus:rec3.forceActiveFocus();break;
caserec2.focus:rec4.forceActiveFocus();break;
caserec3.focus:rec1.forceActiveFocus();break;
caserec4.focus:rec2.forceActiveFocus();break;
}
}
if(event.key==Qt.Key_Left)
{
event.accepted=true;
switch(true)
{
caserec1.focus:rec2.forceActiveFocus();break;
caserec2.focus:rec1.forceActiveFocus();break;
caserec3.focus:rec4.forceActiveFocus();break;
caserec4.focus:rec3.forceActiveFocus();break;
}
}
if(event.key==Qt.Key_Right)
{
event.accepted=true;
switch(true)
{
caserec1.focus:rec2.forceActiveFocus();break;
caserec2.focus:rec1.forceActiveFocus();break;
caserec3.focus:rec4.forceActiveFocus();break;
caserec4.focus:rec3.forceActiveFocus();break;
}
}
}
}
-----------------------------------------------
状态条件
使用状态的另一种方法:
让State决定何时被激活
使用条件判断来决定是否激活一个state
使用when属性
用表达式来判断条件,并返回true或者false
state list中只能有一个state是被激活的:确保一个时间只有一个条件为真
Rectangle {
width: 250; height: 50; color: "#ccffcc"
TextInput {
id: text_field
text: "Enter text..."
...
}
Image {
id: clear_button
source: "../images/clear.svg"
...
MouseArea {
anchors.fill: parent
onClicked: text_field.text = ""
}
}
}
states: [
State {
name: "with text"
when: text_field.text != ""
PropertyChanges { target: clear_button;
opacity: 1.0 }
},
State {
name: "without text"
when: text_field.text == ""
PropertyChanges { target: clear_button;
opacity: 0.25 }
PropertyChanges { target: text_field;
focus: true }
}
]
------------------------------------------------------------------------------
过渡transition元素
Transition元素用于为状态之间的切换提供动画支持
过渡只能被状态切换激活
过渡中的动画可以以串行或者并行的方式执行
通过设置to和from属性,我们可以指定与特定状态绑定的动画
他们默认被设置为“*”,i.e.任意状态//使用*设置只要有状态改变,过渡就会被执行
过渡可以被设置为reversible(默认false)
当条件满足是,自动切换到以前的状态1-》当条件满足是2-》1
----------------------------------------------------------------------------------
可逆过渡reversible
状态如果使用when属性,就可以使用可逆过渡
当两个过渡应用到相同的属性是,可以实现可逆过渡
-------------------------------------------------------------------------------------------
动画
可以对元素的属性变化加入动画
Types:real,int,color,rect,point,size
有三种使用动画的方法
基本的属性动画,过渡,属性行为
动画可以分组:串行或并行的执行
SequentialAnimation,ParallelAnimation,PauseAnimation
预定义的easing curve
OutQuad,InElastic,OutBounce;.....
了解更详细的信息,查看PropertyAnimation文档
使用属性动画,我们使用
ProperyAnimation,NumberAnimation,or ColorAnimation
他们有一个公共的基类:Animation
对于属性行为,使用Behavior
对于过渡,使用Transition
动画实例:
Rectangle {
// Example of a drop-and-bounce effect on an image
id: rect
width: 120; height: 200;
Image {
id: img
source: "qt-logo.png"
x: 60-img.width/2
y: 0
}
}
SequentialAnimation on y {
running: true; loops: Animation.Infinite
NumberAnimation {
to: 200-img.height; easing.type: "OutBounce"; duration: 2000
}
PauseAnimation { duration: 1000 }
NumberAnimation {
to: 0; easing.type: "OutQuad"; duration: 1000
}
}
===============================================
行为属性:behavior
设置一个默认的动画在属性发生改变的时候执行:无论什么造成的属性改变都会执行
Rectangle {
id: redRect
color: "red"
width: 100; height: 100
x: ...
Behavior on x {
NumberAnimation { duration: 300; easing.type: "InOutQuad" }//从x0出现动画移动到x1
}
}
=========================
使用状态和过渡
避免定义过于复杂的状态机
不要用一个状态机来管理所有的UI部分
针对不同的控件使用独立的状态机
然后通过状态把控件的状态联系起来
------------------------------------------------------------------------
状态总结
使用状态来管理其他元素的属性;
定义状态使用元素的state属性
每个状态都必须有独立的名字
给元素设置一个id是很有用的
使用PropertyChanges来修改元素的属性
元素的state属性,保存了当前的状态
可以使用javascript来修改他的值
也可以使用when属性来设1置状态成立条件
---------------------------------------------------------------------------
过渡总结
过渡用来描述状态之间的切换过程
使用transitions属性来定义元素的过渡
过渡需要描述始末的两个状态(from:to),可以使用通配符*来表示所有状态
过渡是可逆的
相当于把from和to属性的值交换reversible:true
=================================================
计时器
计时器使用Timer元素表示的
只提供了一个简单的信号:onTriggered
可以是单次或者重复的计时器
Timer {
interval: 500;
running: true;
repeat: true
onTriggered: time.text = Date().toString()
}
Text {
id: time
}
=================================================
QML核心特征
简单的qml代码包含了QML元素
.qml后缀,编码方式UTF-8
总是以至少一个import语句开始
nothing is imported by default
并没有包含什么代码,仅仅知识为在运行是解释器寻找元素的定义!
定义唯一的顶层QML组件
Self-contained
再执行之前并没有预处理机制
在运行时解释执行!
组件是由QML基本元素构成的
创建自己的组建是非常容易的
组建的名字要以大写字母开始("MyButton.qml")
例子:模块编写
// Definition in MyButton.qml
// (Notice the capital ”M” in the file name above)
import Qt 4.7
Rectangle {
property alias text: textElement.text
width: 100; height: 30
source: "images/toolbutton.sci"
Text {
id: textElement
anchors.centerIn: parent
font.pointSize: 20
style: Text.Raised; color: "white"
}
}
// Usage e.g. in main.qml
// (Just an entry point file, thus lower-case ”m”)
import Qt 4.7
Rectangle {
MyButton {//is the same name as MyButton.qml
anchors.horizontalCenter: parent.horizontalCenter
text: "Orange"
}
...}
--------------------------------------------------------------------------------------
一个组件可以声明为内联组件
用关键字Component声明
可以使用parent的属性或者导入列表中的元素
需要多次在一个QML文件中根据需要被使用(从逻辑上这个组建也只属于这个QML文件)
Inline QML Component内联模块
// In MyComponent.qml
import Qt 4.6
Item {
Component { // The inline component
id: redSquare
Rectangle {
color: "red"
width: 50
height: 50
}
}
Loader { sourceComponent: redSquare }
Loader { sourceComponent: redSquare; x: 70 }
}
---------------------------------------------------------------------------------
QML模块
多个QML组件可以组合到一个QML模块中
最简单的方法是创建一个子文件夹,然后把所有控件放置进去
这些控件可以使用import语句导入到QML的文件中:
import“path_to_mymodule"//path_to_mymodule =文件名
也可以使用命令导入
QML组件也可以在工程外的文件定义
import com.nokia.SomeStuff 1.0// com/nokia/SomeStuff
或者使用qmldir的文件描述import内容
----------------------------------------------------------------------------------
渐进载入
当QML的某个对象引用网络资源的时候,那么它将会提供整个加载过程的进度状态
======================================================================
数据模型和视图
QML使用了与Qt中Model-View类似的结构
模型类提供了数据
模型可以是QML的简单数据,或者复杂的C++数据
QML:ListModel,XmlListModel,VisualItemModel
C++:QAbstractIemModel,QStringList,QList
视图显示模型提供的数据
ListView,GridView,PathView,Repeate(all QML)
都自动支持滚动
代理为视图创建模型中的数据的实例
Hightlight控件用来高亮视图里面的选中item
我们需要来什么?它们是什么?
Model:你的数据
Delegate:(代表)一个描述model中每条数据的显示方式的控件 ,如果是visualItemModel则不需要
View:可视的元素,使用delegate来显示model中的数据
View分为:ListView/GridView/PathView
=================================================
QML高级特性
扩展QML的类型
QML很多核心类型和元素由C++实现,然而用纯QML对这些类型进行扩展也是可能的。
可以:
添加新的属性properties/
添加新的信号signals/
添加新的方法methods/
定义新的QML控件/
添加新属性:property style name:property
新的属性也可以是现有的属性别名:property alias name :property(定义新组件是有用)
只有在控件完全实例化的时候才能使用别名,模块化
添加新的信号:signal xxx()
添加新的方法:
使用JavaScript实现
在QML端可以直接使用,在C++端是槽函数,使用没有类型的参数,(在c++端它的类型为QVariant)
例子:
Item{
id:myItem
function name( parm){
}
}
//use the method
myItem.say("HelloWorld");
==================================================================
QML全局对象
QML提供了全局的JavaScript对象Qt
在QML的任意部分都可以使用
提供了大量的函数
创建QML类型:Qt.rect(...),Qt.rgba(...),Qt.point(...)
做一些其他的常用操作:
Qt.playSound(...),Qt.openUrlExternally(...),Qt.md5(...)
也提供了动态QML对象的创建,AJAX和本地数据访问的接口
----------------------------------------------------------------
在QML中使用JaveScript
JaveScript不能用于为全局对象添加新的成员
在声明变量时,可以省var关键字
两种方法使用JavaScript
lnline JaveScript
独立的javascript文件
-------------------------------
lnline JavaScript
Item{
function factorial(a){
a=parseInt(a);
if(a<=0)
return 1;
else
return a*factorial(a-1);
}
MouseArea{
anchors.fill:parent
onClicked:console.log(factorial(10))
}
}
--------------------------
独立JavaScript文件
import “factorial.js” as Name// 调用的方法:Name.xx()
-----------------------------------------------------------
QML域
当创建了QML组建实例,QML自动为他生成一个于用于:JavaScript的执行和属性的绑定
当系统解析某个引用的时候,作用域的搜索是按照特定的顺序:
JavaScript ariables,functions,and property bindings
attached properties or enumerations