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.