简体   繁体   English

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

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

I (very) occasionally find myself needing to add a property to an item that isn't bindable in other expressions, that is to say that when its value changes, it doesn't notify anything that uses its value and thus doesn't cause expressions to be re-evaluated.我(非常)偶尔会发现自己需要为一个在其他表达式中不可绑定的项目添加一个属性,也就是说,当它的值发生变化时,它不会通知任何使用它的值的东西,因此不会导致要重新评估的表达式。 The point of this is to have essentially what is a pure state variable that can't get itself involved in binding loops.这一点基本上是一个纯 state 变量,它不能让自己参与绑定循环。

As a concrete example:作为一个具体的例子:

Item
{
    property string state: ""

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

        if(state === some_other_external_state)
            return true;

        state = "";
        return false;
    }
}

In this case where some_condition becomes true the visible property sets state and a binding loop occurs since visible depends on the value of state .在这种情况下,当some_condition变为真时, visible属性设置state并发生绑定循环,因为visible取决于state的值。 If the state property didn't bind and was, as its name implies, purely a state variable, this loop is avoided.如果state属性没有绑定,并且正如其名称所暗示的那样,纯粹是一个 state 变量,则可以避免此循环。

One hacky solution that I've used before is:我以前使用过的一种 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;
    }
}

This works because array properties don't notify when the contents of the array change, they only notify when the array itself changes.这是有效的,因为数组属性不会在数组内容更改时发出通知,它们仅在数组本身发生更改时发出通知。 It's not pretty, but it works.它不漂亮,但它有效。

You cannot create non-bindable property in QML. But you can control what bindings will be created.您无法在 QML 中创建不可绑定的属性。但您可以控制将创建哪些绑定。

By design property bindings should not change values of other properties.按照设计,属性绑定不应更改其他属性的值。 This is the source of problem in code sample you provided.这是您提供的代码示例中的问题根源。 There is not enough details to provide full solution but consider this pseudo code:没有足够的细节来提供完整的解决方案,但请考虑以下伪代码:

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'
}

A lot depends on particular design but 2 rules of thumb:很大程度上取决于特定的设计,但有 2 条经验法则:

  • bindings should not alter other properties绑定不应改变其他属性
  • use signal handlers to avoid unwanted bindings使用信号处理程序来避免不需要的绑定

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM