Verwendung von Qt Quick Verhaltensweisen mit Zuständen

Verwendung von Verhaltensweisen mit Zuständen

In manchen Fällen können Sie ein Verhalten verwenden, um eine Eigenschaftsänderung zu animieren, die durch eine Zustandsänderung verursacht wird. Während dies in manchen Situationen gut funktioniert, kann es in anderen Situationen zu unerwartetem Verhalten führen.

Hier ein Beispiel, das das Problem verdeutlicht:

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"
            }
        }
    }
}

Wenn Sie das Beispiel testen, indem Sie die Maus schnell und wiederholt in das farbige Rechteck hinein- und aus ihm herausbewegen, zeigt sich, dass das farbige Rechteck im Laufe der Zeit eine grüne Farbe annimmt und nie wieder vollständig rot wird. Das ist nicht das, was wir wollten! Das Problem tritt auf, weil wir ein Verhalten (Behavior) verwendet haben, um die Farbänderung zu animieren, und unsere Zustandsänderung wird durch das Betreten oder Verlassen des MouseArea durch die Maus ausgelöst, was leicht unterbrochen werden kann.

Um das Problem formaler zu formulieren: Die gemeinsame Verwendung von Zuständen und Verhaltensweisen kann zu unerwartetem Verhalten führen, wenn:

  • ein Verhalten verwendet wird, um eine Eigenschaftsänderung zu animieren, insbesondere beim Wechsel von einem explizit definierten Zustand zurück zum impliziten Basiszustand; und
  • dieses Verhalten unterbrochen werden kann, um einen explizit definierten Zustand (wieder) zu erreichen.

Das Problem ergibt sich aus der Art und Weise, wie der Basiszustand für QML definiert ist: als der "Schnappschuss"-Zustand der Anwendung kurz vor dem Eintritt in einen explizit definierten Zustand. Wenn wir in diesem Fall gerade von Grün zurück nach Rot animieren und die Animation unterbrechen, um zum "GreenState" zurückzukehren, enthält der Basiszustand die Farbe in ihrer Zwischenform in der Mitte der Animation.

Während zukünftige Versionen von QML in der Lage sein sollten, diese Situation besser zu handhaben, gibt es derzeit mehrere Möglichkeiten, Ihre Anwendung zu überarbeiten, um dieses Problem zu vermeiden.

1. Verwenden Sie eine Transition, um die Änderung zu animieren, anstatt ein Behavior.

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. Verwenden Sie eine bedingte Bindung, um den Eigenschaftswert zu ändern, anstelle eines Zustands.

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. Verwenden Sie nur explizit definierte Zustände anstelle eines impliziten Basiszustands.

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.