1

当表达式中的某些内容发生更改时,将更新绑定到表达式的属性。这称为依赖项

编辑:

澄清:

  • 我对 Qt 如何确定依赖项列表的详细信息感兴趣
  • 对简单绑定的依赖,例如x: y或多或少明显
  • x: myItemId["y"]问题是关于不太明显的情况,例如在x: myFunction(z)哪里myFunction(p) { if (p) return myItemId.y }

有时,即使表达式是不带参数的函数调用,QML 引擎也能够检测到更改,有时它不能这样做(例如 mapToItem(item,0,0).x)。

另一个不完美的例子是,在不重新分配数组本身的情况下设置 JS 数组项值通常不会产生 onXxxxxChanged 信号或更新任何引用该数组值的内容。

x: {myForcedDependency; return myActualCalculation()}有时建议使用具有未使用结果 () 的表达式来强制依赖

根据这篇 KDAB 文章Qt 源代码,绑定表达式不仅被评估,而且在此期间“访问”的任何属性都被“捕获”在称为“守卫”的东西中,然后每个守卫属性 onXxxxxChanged() 信号被连接,但实际这个过程的细节尚不清楚。

所以我的问题是:

  • 是否有任何定义的依赖解析规则?

  • 它是如何工作的?

    • QQmlEngine/V8 扫描“访问”到绑定表达式调用的函数的深度有多深,什么可能阻止它这样做?
    • 依赖检测是否仅基于属性解析的第一次尝试?
    • 即使执行从未到达那里,是否检查了所有可能的代码路径?
      • 在这些情况下是否确定了非平凡的访问,例如 object["property"] 语法?
      • 如果某些未执行的代码(当前)是错误的(并且不会产生错误但无法正确分析)怎么办?
  • 如何影响依赖关系解决过程?

    • 有没有办法避免或阻止依赖?
      • 据我了解,只有在需要更新时才真正改变其值的中间“过滤器”属性是预期的方式,对吗?
    • 是否有强制依赖的预期方法?
      • 手动发出“XxxxxChanged”信号是强制更新的正确/支持方式吗?
      • 添加未使用的引用是一种合法/有意的方式,还是基于当前实现怪癖的未定义行为?

任何信息都会很有用,尽管我确实阅读了有关 QML 属性、QML 绑定和 JavaScript 表达式的官方文档,但没有找到任何具体解释 - 如果您参考官方文档,请引用相关部分。

请注意,我并不是要您测试其中任何一个是否适用于您的系统,而是要测试它是否应该有效 - 是否可以依赖它

4

1 回答 1

0

如果您只是将绑定视为连接的信号,则更有意义。如果你有这样的事情:

property int x: y

这就像在 C++ 中这样做:

connect(this, &SomeClass::yChanged, [this]() { x = y; });

表达式也是如此:

property int x: y + z

相当于:

connect(this, &SomeClass::yChanged, [this]() { x = y + z; });
connect(this, &SomeClass::zChanged, [this]() { x = y + z; });

函数调用也是如此:

property int x: someFunc()
function someFunc() {
    return y;
}

绑定不更新的唯一时间是没有要连接的 onChanged 信号,或者由于某种原因没有发出 onChanged 信号。

property int x: cppObject.invokable()

在上述情况下,唯一x能够连接的属性是cppObject。如果invokable引用其他属性,则不会连接到这些属性,x因此绑定不会更新。

property var array: [1, 2, 3]
property int x: array[0]

function updateArray() {
    array = [2, 4, 6]
    arrayChanged()  // Manually call the onChanged signal to update `x`
}

var属性默认情况下不通知(出于某种原因)。所以在这种情况下,我们必须手动调用更改后的信号,但绑定仍然有效。

于 2021-02-22T18:04:16.717 回答