【问题标题】:Order and manner of property binding evaluations in QMLQML 中属性绑定求值的顺序和方式
【发布时间】:2014-11-20 22:51:40
【问题描述】:

据我了解,当在绑定表达式中使用属性时,它们的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 端,我得到非常不一致和不稳定的行为,所以我绝对需要考虑这些工作方式。

【问题讨论】:

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


    【解决方案1】:

    是的。看起来你是对的,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.

    【讨论】:

    • 我在评论部分找到kdab.com/qml-engine-internals-part-2-bindings“仅供参考:首次加载组件时,QML 引擎将尝试以最小化绑定重新评估的顺序评估绑定”,但我想它不会具有很大的价值,因为即使在上述示例这样简单的情况下它也会失败。这对于 Qt 来说似乎非常不专业......
    猜你喜欢
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-24
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    相关资源
    最近更新 更多