Spec-Zone.ru › Qt 5.11

Использование поведений 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API