通常我们将用户界面描述为一种状态。一个状态定义了一组属性的改变,并且会在一定的条件下被触发。另外在这些状态转化的过程中可以有一个过渡,定义了这些属性的动画或者一些附加的动作。当进入一个新的状态时,动作也可以被执行。
1. 状态
1.1 概念
在QML中,使用State元素来定义状态,需要与基础元素对象(Item)的states序列属性连接。状态通过它的状态名来鉴别,由组成它的一系列简单的属性来改变元素。默认的状态在初始化元素属性时定义,并命名为“”(一个空的字符串)。
Item {
id: root
states: [
State {
name: "go"
PropertyChanges { ... }
},
State {
name: "stop"
PropertyChanges { ... }
}
]
}
1.2 牛刀小试
例如一个交通信号灯有两个信号灯。上面的一个信号灯使用红色,下面的信号灯使用绿色。在这个例子中,两个信号灯不会同时发光。让我们看看状态图。
当系统启动时,它会自动切换到停止模式作为默认状态。停止状态改变了light1为红色并且light2为黑色(关闭)。一个外部的事件能够触发现在的状态变换为“go”状态。在go状态下,我们改变颜色属性,light1变为黑色(关闭),light2变为绿色。
为了实现这个方案,我们给这两个灯绘制一个用户界面的草图,为了简单起见,我们使用两个包含园边的矩形框,设置园半径为宽度的一半(宽度与高度相同)。
Rectangle {
id: light
color: "black"
anchors.centerIn: parent
width: 150; height: 3*width
Rectangle {
id: redLight
width: 100; height: width
radius: width/2
color: "red"
visible: true
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -parent.width/2
anchors.horizontalCenter: parent.horizontalCenter
}
Rectangle {
id: greenLight
width: 100; height: width
radius: width/2
color: "green"
visible: true
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: parent.width/2
anchors.horizontalCenter: parent.horizontalCenter
}
//状态
state: "stop"
states: [
State {
name: "stop"
PropertyChanges { target: redLight; visible: true}
PropertyChanges { target: greenLight; visible: false}
},
State {
name: "go"
PropertyChanges { target: redLight; visible: false}
PropertyChanges { target: greenLight; visible: true}
}
]
//鼠标
MouseArea {
anchors.fill: parent
onClicked: parent.state = (parent.state == "stop"? "go":"stop")
}
}
2. 过渡
一系列的过渡能够被加入任何元素,一个过渡由状态的改变触发执行。你可以使用属性的from:和to:来定义状态改变的指定过渡。这两个属性就像一个过滤器,当过滤器为true时,过渡生效。你也可以使用“”来表示任何状态。例如from:“”; to:"*"表示从任一状态到另一个任一状态的默认值,这意味着过渡用于每个状态的切换。
在这个例子中,我们期望从状态“go”到“stop”转换时实现一个颜色改变的动画。对于从“stop”到“go”状态的改变,我们期望保持颜色的直接改变,不使用过渡。我们使用from和to来限制过渡只在从“go”到“stop”时生效。在过渡中我们给每个灯添加两个颜色的动画,这个动画将按照状态的描述来改变属性。
Rectangle {
id: light
color: "black"
anchors.centerIn: parent
width: 150; height: 3*width
Rectangle {
id: redLight
width: 100; height: width
radius: width/2
color: "red"
visible: true
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -parent.width/2
anchors.horizontalCenter: parent.horizontalCenter
}
Rectangle {
id: greenLight
width: 100; height: width
radius: width/2
color: "green"
visible: true
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: parent.width/2
anchors.horizontalCenter: parent.horizontalCenter
}
//状态
state: "stop"
states: [
State {
name: "stop"
PropertyChanges { target: redLight; color: "red"}
PropertyChanges { target: greenLight; color: "black"}
},
State {
name: "go"
PropertyChanges { target: redLight; color: "black"}
PropertyChanges { target: greenLight; color: "green"}
}
]
//过渡
transitions: [
Transition {
from: "stop";to: "go"
ColorAnimation {target: redLight; properties: "color" ;duration: 2000}
ColorAnimation {target: greenLight; properties: "color" ;duration: 2000}
}
]
//鼠标
MouseArea {
anchors.fill: parent
onClicked: parent.state = (parent.state == "stop"? "go":"stop")
}
}
效果图
此处过渡使用的状态的改变,和上面状态改变实现的方法是不相同的。