根据我的理解,当在绑定表达式中使用属性时,它们的NOTIFY
信号被连接起来,表示每次更改属性值时重新评估表达式。
所以考虑一下这个简单的例子:
Rectangle {
width: 200
height: width - 100
Text {
text: "value is " + (parent.width + parent.height)
}
}
其中height
属性绑定到width
属性,text
属性绑定到两者。
在此示例中,不清楚操作顺序是什么。我的意思是如果width
发生变化,它会发出重新评估引用它的两个表达式。但width
也会更改height
,text
本身也会触发text
的评估。
width
属性是否因此被评估两次? width
何时更改,height
更改height
时再次?或者QML有一些优化该行为的机制,例如通知信号不会触发实际的重新评估,而只是标记表达“脏”,并且当所有信令都已传播时,它们会在下一个事件循环迭代中重新评估?即便如此,在更新text
之前,引擎如何知道更新text
以避免对后者进行双重重新评估?或者连接是直接的而不是排队的,并且使用一些更复杂的机制来确定重新评估的顺序?或者也许没有任何类型,{{1}}实际上可能会重新评估两次,如果它恰好是任意顺序?
我真的需要了解它是如何工作的,因为我有一个项目,我在C ++端修改多个QML对象的多个属性,这些属性以命令的方式绑定在QML端,我得到非常不一致和不稳定的行为,所以我肯定需要考虑这些工作的方式。
答案 0 :(得分:2)
是。它看起来你是对的,text
将更新两次。简单的例子:
Rectangle {
id: testRect
width: 200
height: width - 100
Text {
text: "value is " + (parent.width + parent.height)
onTextChanged: {
console.log("text was changed (" + parent.width + "," + parent.height + ")");
}
}
MouseArea {
anchors.fill: parent
onClicked: {
testRect.width = 300
}
}
}
输出:
qml: text was changed (200,100)
qml: text was changed (300,100)
qml: text was changed (300,200)
我猜这是一个简单的行为,并在更改此项目的某些属性时更新相关属性。
Qt docs advices以避免此类情况 - However, if a binding is overly complex - such as involving multiple lines, or imperative loops - it could indicate that the binding is being used for more than describing property relationships. Complex bindings can reduce code performance, readability, and maintainability. It may be a good idea to redesign components that have complex bindings, or at least factor the binding out into a separate function.