Qt属性,底层数据成员,绑定和开销

时间:2014-11-15 16:03:55

标签: c++ qt binding properties qml

我试图绕过这个。我在QML中使用了QObject派生类,它有int length成员和相应的length属性。

QML中90%的时间我通过绑定设置属性:length: 50length: someJSExpression,在这两种情况下,值都由表达式确定,是在50的情况下是微不足道的。

但这是什么意思?底层int仍未使用,而不是从中读取值,它是从绑定表达式计算,还是表达式被计算并且值存储到成员中,然后从中读取?

在第一种情况下,成员只是占用空间而不会被用来产生内存消耗开销,在第二种情况下,开销将来自冗余写/读而不是直接使用表达式中的值而不将其缓存在构件。

在更深层次上,问题将扩展到如何绑定,这些绑定是纯粹的QML事物而不是在C +++ API中使用,无论它们是替换底层属性成员还是与它一起工作和定义(或隐式) getter方法。

另外,在第一种情况下是否有消除头顶空间的空间?我的意思是可以实现一个不使用任何底层成员的只读属性,getter方法可以计算一个表达式来确定它,但在QML的情况下,它不可能使用其他形式,即length = 50暗示设置值而不是将表达式绑定到它?

1 个答案:

答案 0 :(得分:0)

QObject属性链接到QML,因为它们是使用Q_PROPERTY宏在QObject中定义的。你有一个getter(READ),一个setter(WRITE)和一个更改指示器(NOTIFY)。

当QML代码需要设置您的属性时,将调用setter。当QML读取值时,将调用getter。

如果值确实发生变化,你的setter应该发出NOTIFY信号,以便可以重新评估相关的QML表达式。

如何存储属性的值完全取决于您的C ++代码。

使用length: 50初始化QML属性,您的C ++属性将使用您的setter进行初始化,这就是它的全部内容。如果你用length: parent.length + 3之类的东西绑定你的属性,你的C ++属性也将使用你的setter进行初始化,但是QML会安装一个监听器,它监听源值(在上一个例子中为parent.length)并将重新开始 - 每当源值发生变化时,都要评估表达式。因此,如果有人更改parent.length,则会使用parent.length + 3的新评估调用您的setter。

这使得绑定属性的使用非常便宜,只要它们的读取频率高于写入时间。此外,制作大量属性取决于单个属性会增加更改该属性值的成本。

是的,您可以拥有没有setter或基础数据的只读属性。你只需要一些你可以计算的东西。请注意,无论您计算什么,在发出NOTIFY信号之前都不应该改变。否则,将无法更新绑定到您的属性的QML值。