QML scope: property binding in child object failing

落花浮王杯 提交于 2019-12-12 14:41:58

问题


I'm new to QML and ran into a scope problem while going a button tutorial. I solved it but I don't understand why the code didn't work in the first place:

Problem

The following code gives Runtime reference errors when the button is hovered over:

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
        }

    }

errors:

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

Solution

Solved by just moving the property bindings and signal-slot into the Application window object as follows:

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

Questions

Why is it not possible to leave the property bindings within the Rectangle child of the ApplicationWindow object?

What if you wanted to have properties exclusive only to the rectangle (e.g. colour), but that used some of the properties of the ApplicationWindow (e.g. text size)?


I am new to coding and stack overflow (this is my first post). I've tried to ask my question in the clearest way possible, but please let me know if it's not up to par with stack overflow's standards and what I must do to change it.


回答1:


Scope in QML is easy, maybe weird, but easy :

when you use an identifier, lets say foo in a var binding, QML engine search in this order :

  • an object in the urrent file that has foo as its ID
  • an object in global scope (main QML file) that has foo as its ID
  • a property in current object that is called foo
  • a property in the root object of current component (current file) that is called foo

If it does find it, it throws ReferenceError.

And no, immediate parent or child is not in the scope. That can seem weird, but that's the way it works.

If you need an out-of-scope variable to be referenced, just use an ID before it : if the object is called foo and has a property named bar, you can reference foo.bar wherever you wan't in the file.

Hope it helps.



来源:https://stackoverflow.com/questions/23338242/qml-scope-property-binding-in-child-object-failing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!