Qt6 QML Book/动画元素类型/状态和过渡

States and Transitions

状态和过渡

Often parts of a user interface can be described in states. A state defines a set of property changes and can be triggered by a certain condition.

用户界面的某些部分通常可以用状态来描述。状态定义了一组属性更改,并且可以由特定条件触发。

Additionally, these state switches can have a transition attached which defines how these changes should be animated or any additional actions that shall be applied. Actions can also be applied when a state is entered.

此外,这些状态切换可以附加一个过渡,该过渡定义了这些状态切换设置的动画或应用的任何附加操作。当一个状态进入时,也可以应用此操作。

States

状态

You define states in QML with the State element, which needs to be bound to the states array of any item element.

使用State元素类型在QML中定义状态,该元素类型需要绑定到任何item元素的states数组。

A state is identified through a state name, and in its simplest form, consists of a series of property changes on elements. The default state is defined by the initial properties of the element and is named "" (an empty string).

状态是通过状态名标识的,最简单的形式是由元素对象上的一系列属性更改组成。默认状态由元素对象的初始属性定义,并命名为""(空字符串)。

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

A state is changed by assigning a new state name to the state property of the element in which the states are defined.

通过为定义状态的元素的状态属性指定新的状态名称,可以更改状态。

Control states using when

控制状态使用when

Another way to control states is using the when property of the State element. The when property can be set to an expression that evaluates to true when the state should be applied.

控制状态的另一种方法是使用State元素类型的when属性。when属性可以设置为一个表达式,该表达式计算结果为true时,应用状态。

Item {
    id: root
    states: [
        ...
    ]

    Button {
        id: goButton
        ...
        onClicked: root.state = "go"
    }
}

For example, a traffic light might have two signaling lights. The upper one signaling stop with a red color and the lower one signaling go with a green color. In this example, both lights should not shine at the same time. Let’s have a look at the state chart diagram.

例如,一个交通灯可能有两个信号灯。上面的信号灯用红色表示停止,下面的信号灯用绿色表示结束。在本例中,两个灯光不应同时亮起。让我们看看状态图。

When the system is switched on, it automatically goes into the stop mode as the default state. The stop state changes light1 to red and light2 to black (off).

当系统运行时,它会自动进入停止模式作为默认状态。停止状态将light1变为红色,light2变为黑色(关闭)。

An external event can now trigger a state switch to the "go" state. In the go state, we change the color properties from light1 to black (off) and light2 to green to indicate the pedestrians may now cross.

外部事件现在可以触发状态切换到“go”状态。在go状态下,我们更改颜色属性,将light1更改为黑色(关闭),将light2更改为绿色,以指示行人现在可以通过。

To realize this scenario we start sketching our user interface for the 2 lights. For simplicity, we use 2 rectangles with the radius set to the half of the width (and the width is the same as the height, which means it’s a square).

为了实现这个场景,我们开始在用户界面上绘制两个灯光。为简单起见,我们使用2个矩形,半径设置为宽度的一半(宽度与高度相同,这意味着它是正方形)。

Rectangle {
    id: light1
    x: 25; y: 15
    width: 100; height: width
    radius: width / 2
    color: root.black
    border.color: Qt.lighter(color, 1.1)
}

Rectangle {
    id: light2
    x: 25; y: 135
    width: 100; height: width
    radius: width/2
    color: root.black
    border.color: Qt.lighter(color, 1.1)
}

As defined in the state chart we want to have two states: one being the "go" state and the other the "stop" state, where each of them changes the traffic light's respective color to red or green. We set the state property to stop to ensure the initial state of our traffic light is the stop state.

根据状态图中的定义,我们希望有两个状态:一个是“go”状态,另一个是“stop”状态,其中每个状态都将交通灯的各自颜色更改为红色或绿色。我们将state属性设置为stop,以确保红绿灯的初始状态为stop状态。

Initial state

初始状态

We could have achieved the same effect with only a "go" state and no explicit "stop" state by setting the color of light1 to red and the color of light2 to black. The initial state "" defined by the initial property values would then act as the "stop" state.

通过将light1的颜色设置为红色,将light2的颜色设置为黑色,我们可以在只有“go”状态而没有明确的“stop”状态的情况下实现相同的效果。由初始属性值定义的初始状态“”随后将充当“停止”状态。

state: "stop"

states: [
    State {
        name: "stop"
        PropertyChanges { target: light1; color: root.red }
        PropertyChanges { target: light2; color: root.black }
    },
    State {
        name: "go"
        PropertyChanges { target: light1; color: root.black }
        PropertyChanges { target: light2; color: root.green }
    }
]

Using PropertyChanges { target: light2; color: "black" } is not really required in this examples as the initial color of light2 is already black. In a state, it’s only necessary to describe how the properties shall change from their default state (and not from the previous state).

在本例中,不需要使用PropertyChanges{target:light2;color:“black”},因为light2的初始颜色已经是黑色。在一个状态中,只需要描述属性如何从其默认状态(而不是以前的状态)更改。

A state change is triggered using a mouse area which covers the whole traffic light and toggles between the go- and stop-state when clicked.

使用覆盖整个交通灯的鼠标区域触发状态更改,并在单击时在“go”和“stop”状态之间切换。

MouseArea {
    anchors.fill: parent
    onClicked: parent.state = (parent.state == "stop" ? "go" : "stop")
}

We are now able to successfully change the state of the traffic lamp. To make the UI more appealing and natural, we should add some transitions with animation effects. A transition can be triggered by a state change.

我们现在能够成功地改变交通灯的状态。为了使UI更加吸引人和变换自然,我们应该添加一些带有动画效果的过渡。状态切换可以触发过渡。

Using scripting

使用脚本

It’s possible to create similar logic using scripting instead of QML states. However, QML is a better language than JavaScript for describing user interfaces. Where possible, aim to write declarative code instead of imperative code.

也可以使用脚本而不是QML状态创建类似的逻辑。然而,在描述用户界面方面,QML是一种比JavaScript更好的语言。在可能的情况下,目标是编写声明性代码而不是命令式代码。

Transitions

过渡

A series of transitions can be added to every item. A transition is executed by a state change.

可以向每个项目添加一系列过渡。过渡是在状态间切换时执行的。

You can define on which state change a particular transition can be applied using the from: and to: properties. These two properties act like a filter: when the filter is true the transition will be applied. You can also use the wildcard “*”, which means “any state”.

您可以使用from:和to:属性定义可以应用特定过渡的状态切换。这两个属性的作用类似于过滤器:当过滤器为true时,将应用过渡。您还可以使用通配符“*”,它表示“任何状态”。

For example, from: "*"; to: "*" means "from any state to any other state", and is the default value for from and to. This means the transition will be applied to every state switch.

例如,from: "*"; to: "*" 表示“从任何状态到任何其他状态”,是from和to的默认值。这意味着过渡将应用于每个状态切换。

For this example, we would like to animate the color changes when switching state from “go” to “stop”. For the other reversed state change (“stop” to “go”) we want to keep an immediate color change and don’t apply a transition.

对于本例,我们希望在将状态从“go”切换到“stop”时,增加颜色切换时的动画。对于另一个反向状态更改(“stop”到“go”),我们希望保持颜色立即变化,而不使用过渡动画。

We restrict the transition with the from and to properties to filter only the state change from “go” to “stop”. Inside the transition, we add two color animations for each light, which shall animate the property changes defined in the state description.

我们使用from和to属性限制转换,以仅过滤从“go”到“stop”的状态切换。在过渡内部,我们为每个灯光添加两个颜色动画,这将为状态描述中定义的属性增加切换动画。

transitions: [
    Transition {
        from: "stop"; to: "go"
        // from: "*"; to: "*"
        ColorAnimation { target: light1; properties: "color"; duration: 2000 }
        ColorAnimation { target: light2; properties: "color"; duration: 2000 }
    }
]

You can change the state though clicking the UI. The state is applied immediately and will also change the state while a transition is running. So, try to click the UI while the state is in the transition from “stop” to “go”. You will see the change will happen immediately.

您可以通过单击UI来切换状态。状态将立即开始切换,并且在过渡运行时将状态切换完成。因此,当状态从“stop”转换为“go”时,尝试单击UI。你会看到切换会立即完成。

You could play around with this UI by, for example, scaling the inactive light down to highlight the active light.

例如,可以通过缩小非活动灯光,并高亮显示活动灯光来使用此UI。

For this, you would need to add another property change for scaling to the states and also handle the animation for the scaling property in the transition.

为此,需要状态中添加另一个属性变化,并在过渡中处理缩放属性的动画。

Another option would be to add an “attention” state where the lights are blinking yellow. For this, you would need to add a sequential animation to the transition for one second going to yellow (“to” property of the animation and one second going to “black”).

另一个可选的是添加一个“attention”状态,其中指示灯呈黄色闪烁。为此,需要将连续动画添加到过渡中,一秒钟变为黄色(“to”动画属性,一秒钟变为“黑色”)。

Maybe you would also want to change the easing curve to make it more visually appealing.

也许您还想更改缓和曲线,使其在视觉上更具吸引力。

示例源码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值