【问题标题】:How can I avoid creating a property binding on initialization in QML?如何避免在 QML 初始化时创建属性绑定?
【发布时间】:2013-10-23 20:10:20
【问题描述】:

我想创建一个具有两个属性onetwo 的自定义QML 组件,它们在未初始化时应该具有默认值。特别是,如果two 应该得到一个依赖于one 的初始值。以下代码

Rectangle {
  property int one: 1
  property int two: 2 * one
}

但是会创建一个属性绑定:每当one 更改时,two 就会更新为2 * one 的新值。如何在不创建绑定的情况下将two 初始化为2 * one

【问题讨论】:

  • 您可以做的一种方法是在 Component.onCompleted 上手动初始化它,但这似乎不是理想的方式

标签: qt qml


【解决方案1】:

一种明确告诉您不需要绑定的方法是在表达式块中调用赋值:

Rectangle {
  property int one: 1
  property int two: {two = 2 * one}
}

与在onCompleted中打破绑定的方法不同,表达式块避免了绑定对象的创建和销毁,看起来更干净。

【讨论】:

  • 非常聪明的答案。我一直在处理这个问题。很多时候,由于初始化绑定,我进入了绑定循环。这样,我有一个非常干净的代码,没有丑陋的 onCompleted 技巧。非常感谢你。大赞!
【解决方案2】:

在组件完成时显式中断绑定:

Rectangle {
    property int one: 1
    property int two: 2 * one
    Component.onCompleted: two = two
}

two = two 分配打破了绑定,two 不再随着one 的变化而更新。

【讨论】:

    【解决方案3】:

    仔细检查是否需要 Binding 并注意不要弄脏代码。
    您可以按如下方式尽快为属性填充值:

    window {
        id: win
        width: 300; height: 450
        color: "#d8d8d8"
        Item {
            property int val1
            property int val2
            property int val3: parent.width    //<-- Binding
            Component.onCompleted: {
                val1 = win.width;    //<---|
                val2 = win.height;   //<---|=== There is no binding. Just changes value
                /* ... */
            }
        }
    }
    

    (我不确定,您可能可以使用Component.onStatusChangedComponent.Ready 状态设置初始值)

    性能注意事项:信号和 Javascript 代码对性能有一定影响。使用绑定可能会更高效。使用 Profiler 进行检查。如果你想设置多个属性的初始值或者你已经使用了onCompleted信号,那么这将提高性能!

    【讨论】:

      【解决方案4】:

      事实上,你不应该这样做。绑定是 QML 的基本行为,如果你试图避免它,那是因为你没有考虑好的方法。

      例如,如果属性二初始值是用属性一初始值而不是属性一值计算的,

      那意味着你想绑定初始值而不是,你应该创建一个只读属性,其值为属性一初始值

      readonly property int initialOne : 1;
      property int one : initialOne;
      property int two : 2 * initialOne;
      

      它可能看起来有点沉重,但如果你仔细想想,初始值就是你想要使用的,所以,属性的概念就是你真正想要的

      【讨论】:

      • 如果 initialOne 依赖于 parent.width(例如)像 readonly property int initialOne : parent.width 怎么办?
      • 如果我可以在某些情况下避免不必要的绑定,那我为什么要这样做呢?在某些情况下不需要绑定。想象一下创建一个具有明确或不可更改大小的应用程序(例如在移动设备上发生的情况)。在这种情况下,不需要绑定宽度或高度等。您可能需要立即更改属性,以后的任何值更改都不重要。想象一下使用PropertyChanges 并且值通常会发生变化。绑定及其开销是否必要?!
      • @S.M.Mousavi :不,你是对的,绑定并不总是必要的。但是当您根据计算定义属性时,Qml 属性与变量不同。您正在定义这两个属性之间的关系。如果你想让一个属性有一个基于计算的值,以后不会改变,你不应该使用属性,你应该使用变量
      • @BlueMagma:你是对的!但据我记得,文档建议避免使用全局 javascript 变量来解决性能问题,而是使用 QML 属性。另见stackoverflow.com/a/20934781/1074799
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      相关资源
      最近更新 更多