QML中属性绑定评估的顺序和方式



据我了解,当属性在绑定表达式中使用时,它们的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?或者,也许QML具有某种优化该行为的机制,例如,通知信号不会触发实际的重新评估,而只会将表达式标记为"脏",并且在所有信号都已传播后,在下一次事件循环迭代中重新评估它们?即便如此,引擎如何知道在更新text之前更新height以避免后者的双重重新评估?或者也许连接是直接的而不是排队的,并且使用一些更复杂的机制来计算重新评估的顺序?或者也许没有这种东西,如果恰好是任意顺序,text实际上可能会重新评估两次?

真的需要了解这是如何工作的,因为我有一个项目,我以命令式方式修改C++端多个 QML 对象的多个属性,这些属性绑定在 QML 端,并且我得到了非常不一致和不稳定的行为,所以我绝对需要考虑这些工作方式。

是的。 看起来你是对的,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文档建议避免这种情况 - 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.

最新更新