qml id转字符串_QML中的状态与过渡-一起做一个红绿灯

cda54a9189c57bcc9e1288b9b89c06d6.png

前言

通常我们将用户界面描述为一种状态。一个状态定义了一组属性的改变,并且会在一定的条件下被触发。另外在这些状态转化的过程中可以有一个过渡,定义了这些属性的动画或者一些附加的动作。当进入一个新的状态时,动作也可以被执行。

状态

在QML中,使用State元素来定义状态,需要与基础元素对象Item的states序列属性连接,状态通过它的状态名来鉴别,由组成它的一系列简单的属性来改变元素。默认的状态在初始化元素属性时定义,并命名为“”(一个空的字符串)。

可以通过给一个元素分配新的状态属性名来改变状态,例如:

Item {    id: root    states: [        State {            name: "go"            PropertyChanges { ... }        },        State {            name: "stop"            PropertyChanges { ... }        }    ]}

另一种切换属性的方法是使用状态元素的when属性。when属性能够被设置为一个表达式的结果,当结果为true时,状态被使用。

Item {    id: root    states: [        ...    ]        Button {        id: goButton        ...        onClicked: root.state = "go"    }}

红绿灯的实现

bac3647cf59eaf466bd4a0224baabf6b.png

我们都知道马路上的红绿灯上有红绿黄三个信号灯,且两个信号灯不会同时亮,我们通过状态的改变来实现一个简单的红绿灯。为了简单起见,我们使用三个包含圆边的矩形框,设置圆的半径为宽度的一半,宽度与高度相同。我们使鼠标区域覆盖整个界面,并且在鼠标点击时进行状态的切换来改变灯的颜色。

import QtQuick 2.3import QtQuick.Window 2.2Window {    id: root    visible: true    width: 640    height: 480    Item {        anchors.fill: parent        Rectangle {            id: redlight            x: 25; y: 15            width: 100; height: width            radius: width / 2            color: "black"        }        Rectangle {            id: greenlight            x: 25; y: 135            width: 100; height: width            radius: width / 2            color: "black"        }        Rectangle {            id: yellowlight            x: 25; y: 255            width: 100; height: width            radius: width / 2            color: "black"        }        state: "red"        states: [            State {                name: "red"                PropertyChanges { target: redlight; color: "red" }                PropertyChanges { target: greenlight; color: "black" }                PropertyChanges { target: yellowlight; color: "black" }            },            State {                name: "green"                PropertyChanges { target: redlight; color: "black" }                PropertyChanges { target: greenlight; color: "green" }                PropertyChanges { target: yellowlight; color: "black" }            },            State {                name: "yellow"                PropertyChanges { target: redlight; color: "black" }                PropertyChanges { target: greenlight; color: "black" }                PropertyChanges { target: yellowlight; color: "yellow" }            }        ]        MouseArea {            anchors.fill: parent            onClicked: {                if (parent.state == "red")                    parent.state = "green";                else if (parent.state == "green")                    parent.state = "yellow";                else if (parent.state == "yellow")                    parent.state = "red";            }        }    }}

运行效果如下:

481fa3dd95f285d801620ebc8049d97a.gif

上面我们已经成功实现了红绿灯的效果。但是为了让用户界面看起来更加的自然,我们下面将使用动画效果来增加一些过渡。一个过渡也能被状态的改变触发。

过渡

一系列的过渡能够加入任何元素中,一个过渡由状态的改变触发执行。你可以使用属性的from:和to:来定义状态改变的过渡。这两个属性就像一个过滤器,当过滤器为true时,过渡生效。你也可以使用“”来表示任何状态。

接下来我们来改造一下上面的例子,在其中添加一个灯光改变的动画。在过渡中我们给每个灯添加两个颜色的动画,这个动画将按照状态的描述来改变属性,每个动画支持1000。

import QtQuick 2.3import QtQuick.Window 2.2Window {    id: root    visible: true    width: 640    height: 480    Item {        anchors.fill: parent        Rectangle {            id: redlight            x: 25; y: 15            width: 100; height: width            radius: width / 2            color: "black"        }        Rectangle {            id: greenlight            x: 25; y: 135            width: 100; height: width            radius: width / 2            color: "black"        }        Rectangle {            id: yellowlight            x: 25; y: 255            width: 100; height: width            radius: width / 2            color: "black"        }        state: "red"        states: [            State {                name: "red"                PropertyChanges { target: redlight; color: "red" }                PropertyChanges { target: greenlight; color: "black" }                PropertyChanges { target: yellowlight; color: "black" }            },            State {                name: "green"                PropertyChanges { target: redlight; color: "black" }                PropertyChanges { target: greenlight; color: "green" }                PropertyChanges { target: yellowlight; color: "black" }            },            State {                name: "yellow"                PropertyChanges { target: redlight; color: "black" }                PropertyChanges { target: greenlight; color: "black" }                PropertyChanges { target: yellowlight; color: "yellow" }            }        ]        transitions: [            Transition {                from: "red"                to: "green"                ColorAnimation { target: redlight; properties: "color"; duration: 1000 }                ColorAnimation { target: greenlight; properties: "color"; duration: 1000 }            },            Transition {                from: "green"                to: "yellow"                ColorAnimation { target: greenlight; properties: "color"; duration: 1000 }                ColorAnimation { target: yellowlight; properties: "color"; duration: 1000 }            },            Transition {                from: "yellow"                to: "red"                ColorAnimation { target: yellowlight; properties: "color"; duration: 1000 }                ColorAnimation { target: redlight; properties: "color"; duration: 1000 }            }        ]        MouseArea {            anchors.fill: parent            onClicked: {                if (parent.state == "red")                    parent.state = "green";                else if (parent.state == "green")                    parent.state = "yellow";                else if (parent.state == "yellow")                    parent.state = "red";            }        }    }}

运行效果如下:

1af7d5e575b9bf11e5cc1aa2f9b60e41.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值