Использование поведений 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/archives/qt-5.6/qtquick-statesanimations-behaviors.html