Sur cette page

Utilisation de l'Qt Quick Utilisation des comportements avec les états

Utilisation des comportements avec les états

Dans certains cas, vous pouvez choisir d’utiliser un comportement pour animer une modification de propriété provoquée par un changement d’état. Si cela fonctionne bien dans certaines situations, cela peut toutefois entraîner un comportement inattendu dans d’autres.

Voici un exemple illustrant le problème :

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

En testant l'exemple en déplaçant rapidement et de manière répétée la souris à l'intérieur et à l'extérieur du rectangle coloré, on constate que celui-ci finit par prendre une couleur verte au fil du temps, sans jamais revenir au rouge vif. Ce n'est pas le résultat escompté ! Le problème survient parce que nous avons utilisé un comportement pour animer le changement de couleur, et que notre changement d’état est déclenché par l’entrée ou la sortie de la souris de l’ MouseArea, ce qui peut facilement être interrompu.

Pour formuler le problème de manière plus formelle, l’utilisation conjointe des états et des comportements peut entraîner un comportement inattendu lorsque :

  • un « Behavior » est utilisé pour animer un changement de propriété, en particulier lors du passage d’un état explicitement défini vers l’état de base implicite ; et
  • ce « Behavior » peut être interrompu pour (re)passer dans un état explicitement défini.

Le problème provient de la manière dont l’état de base est défini en QML : il s’agit de l’état « instantané » de l’application juste avant d’entrer dans un état explicitement défini. Dans ce cas, si l’on est en train d’animer le passage du vert au rouge et que l’on interrompt l’animation pour revenir à « GreenState », l’état de base inclura la couleur sous sa forme intermédiaire, à mi-animation.

Bien que les futures versions de QML devraient pouvoir gérer cette situation de manière plus fluide, il existe actuellement plusieurs façons de remanier votre application pour éviter ce problème.

1. Utilisez une transition pour animer le changement, plutôt qu’un comportement.

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. Utilisez une liaison conditionnelle pour modifier la valeur de la propriété, plutôt qu’un état

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. N’utilisez que des états explicitement définis, plutôt qu’un état de base implicite

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

© 2026 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.