Использование поведений 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"
}
}]
}
}
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/qtquick-statesanimations-behaviors.html