QML范围:子对象中的属性绑定失败

时间:2014-04-28 10:08:51

标签: scope qt-creator qml property-binding

我是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

解决方案

解决方法是将属性绑定和信号槽移动到Application窗口对象中,如下所示:

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的某些属性(例如文本大小),该怎么办?


我是编码和堆栈溢出的新手(这是我的第一篇文章)。我试图以最清晰的方式提出我的问题,但是如果它不符合堆栈溢出的标准以及我必须做些什么来改变它,请告诉我。

1 个答案:

答案 0 :(得分:4)

QML中的范围很简单,可能很奇怪,但很容易:

当您使用标识符时,在var绑定中说foo,QML引擎按此顺序搜索:

  • urrent文件中的对象,其{ID为{1}}
  • 全局范围中的对象 <(主要QML文件),其{ID为{1}}
  • 当前对象中的属性,名为foo
  • 当前组件(当前文件)的根对象中的属性,名为foo

如果找到它,它会抛出foo

不,直接的父母或孩子不在范围内。这看起来很奇怪,但这就是它的工作方式。

如果需要引用超出范围的变量,只需在其前面使用ID:如果对象名为foo并且具有名为ReferenceError的属性,则可以引用{{ 1}}无论你在文件中的哪个地方。

希望它有所帮助。