状态描述了当前用户界面样子,QML中一个状态定义了一组属性的改变,并且会在一定条件下被触发。

假设有这么一个场景,红黄绿三个灯,用一个按钮,点击后依次切换三个灯亮起。使用QWidget的思路去实现就是在按钮click对应的槽函数中,依次获取三个button的指针,然后改变其颜色,这样也能实现,但是不够优雅。QML的思路是,全局定义一组状态,然后每个状态来控制具体的属性,使用时只要切换不同状态就可以了,后续修改的话,只需要修改这个全局状态就行,并且三个按钮集中暴露在这组状态中。

一,定义三个灯

//三个灯的按钮
Row{
anchors.centerIn: parent
spacing: 20
//红灯
Rectangle{
id:red
width: 50
height: 50
radius: 50
color: "red"
}

//黄灯
Rectangle{
id:yellow
width: 50
height: 50
radius: 50
color: "yellow"
}

//绿灯
Rectangle{
id:green
width: 50
height: 50
radius: 50
color: "green"
}
}

二,定义一组状态,每个状态控制 三个灯具体的属性

//定义一组状态 规定每个状态下 的属性
Item{
id:root
state:"red"
states: [
State {
//红灯状态 红灯亮 其它灭
name: "red"
PropertyChanges {target: red;color:"red"}
PropertyChanges {target: yellow;color:"gray"}
PropertyChanges {target: green;color:"gray"}
},
State {
name: "yellow"
PropertyChanges {target: yellow;color:"yellow"}
PropertyChanges {target: red;color:"gray"}
PropertyChanges {target: green;color:"gray"}
},
State {
name: "green"
PropertyChanges {target: green;color:"green"}
PropertyChanges {target: red;color:"gray"}
PropertyChanges {target: yellow;color:"gray"}
}
]
}

三,切换时 只需要指定 当前状态是 谁即可。

//依次切换三个状态
Button{
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("切换")
onClicked: {
if(root.state=="red")
root.state="yellow"
else if(root.state=="yellow")
root.state="green"
else
root.state="red"
}
}

四,效果

五,过渡

我们还可以在状态切换的时候,加上过渡的动画,让其看起来更丝滑。过渡规定了从状态A到状态B切换时,某个动画的变化。比如下边状态红灯 到黄灯时,红灯和黄灯颜色持续500毫秒。

六,代码

https://gitcode.com/keiler20181/QMLState.git