3

私は QML を初めて使用し、ボタンのチュートリアルを行っているときにスコープの問題に遭遇しました。私はそれを解決しましたが、そもそもコードが機能しなかった理由がわかりません:

問題

次のコードは、ボタンをホバーしたときにランタイム参照エラーを発生させます。

main_broken.qml

    import QtQuick 2.0
    import QtQuick.Controls 1.1

    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: qsTr("Button Tester")

        Rectangle {
                id: simpleButton
                height: 75
                width: 150
                property color buttonColor: "light blue"
                property color onHoverColor: "gold"
                property color borderColor: "white"

                onButtonClick: {
                        console.log(buttonLabel.text + " clicked")
                }

                signal buttonClick()



                Text {
                    id: buttonLabel
                    anchors.centerIn: parent
                    text: "button label"
                }

                MouseArea {
                    id: buttonMouseArea
                    anchors.fill: parent
                    onClicked: buttonClick()
                    hoverEnabled: true
                    onEntered: parent.border.color = onHoverColor
                    onExited: parent.border.color = borderColor
                }

                color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor
                scale: buttonMouseArea.pressed ? 0.99 : 1
        }

    }

エラー:

qrc:///main.qml:37: ReferenceError: onHoverColor is not defined
qrc:///main.qml:38: ReferenceError: borderColor is not defined
qrc:///main.qml:37: ReferenceError: onHoverColor is not defined
qrc:///main.qml:35: ReferenceError: buttonClick is not defined

解決

次のように、プロパティ バインディングとシグナル スロットをアプリケーション ウィンドウ オブジェクトに移動するだけで解決されます。

main_fixed.qml

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Button Tester")

    property color buttonColor: "light blue"
    property color onHoverColor: "gold"
    property color borderColor: "white"

    onButtonClick: {
            console.log(buttonLabel.text + " clicked")
    }

    signal buttonClick()

    //etc

質問

ApplicationWindow オブジェクトの子 Rectangle 内にプロパティ バインディングを残すことができないのはなぜですか?

四角形専用のプロパティ (色など) が必要で、ApplicationWindow のプロパティの一部 (テキスト サイズなど) を使用する場合はどうすればよいでしょうか?


私はコーディングとスタック オーバーフローが初めてです (これが私の最初の投稿です)。可能な限り明確な方法で質問をしようとしましたが、スタック オーバーフローの基準に達していない場合と、それを変更するために何をしなければならないかを教えてください。

4

1 に答える 1

4

QML のスコープは簡単です。おそらく奇妙ですが、簡単です。

識別子を使用する場合foo、var バインディングでは、QML エンジンは次の順序で検索します。

  • IDを持つ現在のファイル内のオブジェクトfoo
  • IDを持つグローバル スコープ(メイン QML ファイル)のオブジェクトfoo
  • 呼び出される現在のオブジェクトプロパティfoo
  • 呼び出される現在のコンポーネント (現在のファイル)のルート オブジェクトプロパティfoo

見つからない場合は、 をスローしReferenceErrorます。

いいえ、直接の親または子はスコープ内にありません。奇妙に思えるかもしれませんが、それが機能する方法です。

範囲外の変数を参照する必要がある場合は、その前に ID を使用します。オブジェクトが呼び出されfoo、 という名前のプロパティがある場合、ファイル内のどこにいてbarも参照できます。foo.bar

それが役に立てば幸い。

于 2014-04-28T14:53:14.897 に答える