Qt Quick 行为与状态结合使用

将行为与状态结合使用

在某些情况下,您可能会选择使用行为来为状态变化引起的属性变化制作动画。虽然这在某些情况下效果很好,但在其他情况下可能会导致意想不到的行为。

下面的示例可以说明这个问题:

import QtQuick 2.0

Rectangle {
    width: 400
    height: 400

    Rectangle {
        id: coloredRect
        width: 100
        height: 100
        anchors.centerIn: parent

        color: "red"
        Behavior on color {
            ColorAnimation {}
        }

        MouseArea {
            id: mouser
            anchors.fill: parent
            hoverEnabled: true
        }

        states: State {
            name: "GreenState"
            when: mouser.containsMouse

            PropertyChanges {
                target: coloredRect
                color: "green"
            }
        }
    }
}

通过快速、反复地将鼠标移入或移出彩色矩形来测试该示例,结果显示彩色矩形会随着时间的推移逐渐变成绿色,而永远不会恢复到全红色。这不是我们想要的结果!出现这个问题的原因是,我们使用了行为来制作颜色变化的动画,而我们的状态变化是通过鼠标进入或退出MouseArea 来触发的,这很容易被中断。

为了更正式地说明这个问题,在以下情况下,同时使用状态和行为可能会导致意想不到的行为:

  • 行为被用于为属性变化制作动画,特别是从显式定义的状态返回到隐式基本状态时;以及
  • 该行为会被中断以(重新)进入显式定义的状态。

问题出现的原因是 QML 对基态的定义方式:即进入显式定义状态前的应用程序 "快照 "状态。在这种情况下,如果我们正在从绿色动画返回到红色动画,并中断动画返回到 "GreenState"(绿色状态),基态将包括中间的、动画中间形式的颜色。

虽然未来版本的 QML 应该能更优雅地处理这种情况,但目前有几种方法可以重新设计您的应用程序来避免这个问题。

1.使用过渡动画而不是行为变化。

import QtQuick 2.0

Rectangle {
    width: 400
    height: 400

    Rectangle {
        id: coloredRect
        width: 100
        height: 100
        anchors.centerIn: parent

        color: "red"

        MouseArea {
            id: mouser
            anchors.fill: parent
            hoverEnabled: true
        }

        states: State {
            name: "GreenState"
            when: mouser.containsMouse

            PropertyChanges {
                target: coloredRect
                color: "green"
            }
        }

        transitions: Transition {
            ColorAnimation {}
        }
    }
}

2.使用条件绑定来改变属性值,而不是状态

import QtQuick 2.0

Rectangle {
    width: 400
    height: 400

    Rectangle {
        id: coloredRect
        width: 100
        height: 100
        anchors.centerIn: parent

        color: mouser.containsMouse ? "green" : "red"
        Behavior on color {
            ColorAnimation {}
        }

        MouseArea {
            id: mouser
            anchors.fill: parent
            hoverEnabled: true
        }
    }
}

3.只使用明确定义的状态,而不是隐含的基本状态

import QtQuick 2.0

Rectangle {
    width: 400
    height: 400

    Rectangle {
        id: coloredRect
        width: 100
        height: 100
        anchors.centerIn: parent

        Behavior on color {
            ColorAnimation {}
        }

        MouseArea {
            id: mouser
            anchors.fill: parent
            hoverEnabled: true
        }

        states: [
        State {
            name: "GreenState"
            when: mouser.containsMouse

            PropertyChanges {
                target: coloredRect
                color: "green"
            }
        },
        State {
            name: "RedState"
            when: !mouser.containsMouse

            PropertyChanges {
                target: coloredRect
                color: "red"
            }
        }]
    }
}

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.