Qtクイックビヘイビアとステート

ステートでビヘイビアを使用する

ビヘイビアを使用して、ステートの変化によるプロパティの変化をアニメーションさせる場合があります。これは、ある状況ではうまくいきますが、別の状況では予期せぬ動作につながる可能性があります。

以下に、この問題を示す例を示します:

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"
            }
        }]
    }
}

©2024 The Qt Company Ltd. 本ドキュメントに含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。