我怎样才能给 Qt QML 项目一个 属性 ,当它改变时不通知?

How can I give a Qt QML item a property that doesn't notify when it changes?

我(非常)偶尔发现自己需要给一个在其他表达式中不可绑定的项目添加一个 属性,也就是说当它的值改变时,它 不会't 通知任何使用其值的事物,因此 不会 导致重新计算表达式。这样做的重点是本质上是一个不能让自己参与绑定循环的纯状态变量。

举个具体的例子:

Item
{
    property string state: ""

    visible:
    {
        if(some_condition)
        {
            state = "foo";
            return true;
        }

        if(state === some_other_external_state)
            return true;

        state = "";
        return false;
    }
}

在这种情况下,some_condition 变为真,visible 属性 设置 state 并发生绑定循环,因为 visible 取决于 state。如果 state 属性 没有绑定,并且正如其名称所暗示的那样,纯粹是一个状态变量,则可以避免此循环。

我以前用过的一个 hacky 解决方案是:

Item
{
    property var state: [""]

    visible:
    {
        if(some_condition)
        {
            state[0] = "foo";
            return true;
        }

        if(state[0] === some_other_external_state)
            return true;

        state[0] = "";
        return false;
    }
}

之所以可行,是因为数组属性不会在数组内容发生变化时发出通知,它们只会在数组本身发生变化时发出通知。它不漂亮,但它有效。

您不能在 QML 中创建 non-bindable 属性。但是您可以控制将创建哪些绑定。

根据设计 属性 绑定不应更改其他属性的值。这是您提供的代码示例中的问题根源。没有足够的细节来提供完整的解决方案,但请考虑以下伪代码:

Item {
   // Item has state property already - you should not redefine it
   // property string state: ""

   visible: state !== "" // or whatever else is correct, but keep it simple
   // Optionally:
   onVisibleChanged: {
      // Any extra operations that should be done
      // when item is being shown or hidden
      // But you should not change state variable here!
   }
   
   // Monitor all events that should change state and keep it up to date
   // Usually Qt will already have a signal notifying about particular change 
   // or you can define signals you need and emit in proper places 
   Connections {
      target: other_object
      onSignalForSomeSpecificEvent: state = "bar"
   }   

   // Some conditions you can define in declarative form
   // Suitable for condition depending on other properties
   property bool someCondition 
   onSomeConditionChaged: state = 'foo'
}

很大程度上取决于特定的设计,但有 2 条经验法则:

  • 绑定不应改变其他属性
  • 使用信号处理程序来避免不需要的绑定