问题
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