QML中的财产约束评估的顺序和方式

时间:2014-11-20 22:51:40

标签: c++ binding properties qml signals-slots

根据我的理解,当在绑定表达式中使用属性时,它们的NOTIFY信号被连接起来,表示每次更改属性值时重新评估表达式。

所以考虑一下这个简单的例子:

Rectangle {
    width: 200
    height: width - 100

    Text {
        text: "value is " + (parent.width + parent.height)
    }
}

其中height属性绑定到width属性,text属性绑定到两者。

在此示例中,不清楚操作顺序是什么。我的意思是如果width发生变化,它会发出重新评估引用它的两个表达式。但width也会更改heighttext本身也会触发text的评估。

width属性是否因此被评估两次? width何时更改,height更改height时再次?或者QML有一些优化该行为的机制,例如通知信号不会触发实际的重新评估,而只是标记表达“脏”,并且当所有信令都已传播时,它们会在下一个事件循环迭代中重新评估?即便如此,在更新text之前,引擎如何知道更新text以避免对后者进行双重重新评估?或者连接是直接的而不是排队的,并且使用一些更复杂的机制来确定重新评估的顺序?或者也许没有任何类型,{{1}}实际上可能会重新评估两次,如果它恰好是任意顺序?

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

1 个答案:

答案 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.