Uso de comportamientos con estados en Qt Quick
Uso de Comportamientos con Estados
En algunos casos puedes elegir utilizar un Comportamiento para animar un cambio de propiedad causado por un cambio de estado. Mientras que esto funciona bien en algunas situaciones, en otras puede conducir a un comportamiento inesperado.
Aquí hay un ejemplo que muestra el problema:
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" } } } }
Al probar el ejemplo moviendo rápida y repetidamente el ratón dentro y fuera del rectángulo de color, se muestra que el rectángulo de color se asentará en un color verde con el tiempo, sin volver nunca al rojo completo. Esto no es lo que queríamos. El problema se produce porque hemos utilizado un Behavior para animar el cambio de color, y nuestro cambio de estado se activa cuando el ratón entra o sale de MouseArea, lo que se interrumpe fácilmente.
Para plantear el problema de manera más formal, el uso de Estados y Comportamientos juntos puede causar un comportamiento inesperado cuando:
- se utiliza un Comportamiento para animar un cambio de propiedad, concretamente al pasar de un estado definido explícitamente al estado base implícito; y
- este Comportamiento puede interrumpirse para (re)entrar en un estado definido explícitamente.
El problema surge por la forma en que se define el estado base para QML: como el estado "instantáneo" de la aplicación justo antes de entrar en un estado definido explícitamente. En este caso, si estamos en el proceso de animar de verde a rojo, e interrumpimos la animación para volver a "GreenState", el estado base incluirá el color en su forma intermedia, a mitad de la animación.
Mientras que las futuras versiones de QML deberían ser capaces de manejar esta situación con más gracia, actualmente hay varias maneras de reelaborar su aplicación para evitar este problema.
1. Utilice una transición para animar el cambio, en lugar de un Comportamiento.
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. Utilice un enlace condicional para cambiar el valor de la propiedad, en lugar de un estado
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. Utilice sólo estados definidos explícitamente, en lugar de un estado base implícito.
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.