c++ 如何在QML中创建元素的过程中更改属性绑定?

lymnna71  于 2023-02-01  发布在  其他
关注(0)|答案(2)|浏览(119)

假设我有一个定制的CheckBox

//MyCheckBox.qml

CheckBox {
  required property QtObject proxy

  checked: proxy.value

  Binding {
    target:    proxy
    property:  "value"
    value:     checked
  }
}

因此,MyCheckBox的选中状态绑定到我的对象(proxy)的value属性**,反之亦然**,也就是说,我有一个双向绑定。
我使用的自定义复选框如下:

//My window
Item {

  ...

  MyCheckBox {
    id:    ordinaryCheck
    proxy: ...
  }

  ...
}

一切都按预期运行,但如果我需要反转MyCheckBox的某个示例的逻辑,该怎么办?* 当proxy.value为true时,复选框未选中,而当proxy.value为false时,复选框选中 *?但是,ofc,不起作用,因为如果我尝试这样做,这里有一个绑定循环:

Item {

...

  MyCheckBox {
    id:    invertedCheck

    proxy:     ...
    checked:   !proxy.value

    Binding {
      target:    proxy.value
      property:  "value"
      value:     !checked
    }
}

Qt绑定也不是一个选项:

//MyCheckBox.qml

CheckBox {
  required property QtObject proxy

  checked: proxy.value

  Component.onCompleted {
    property.value = Qt.binding(function() { return checked });
  }
}

在本例中,我遇到了相同的 * 绑定循环错误 *。
那么,要达到这个目标,我的选择是什么?如何在示例化的时候替换绑定?

更新1

下面是我的PropertyProxy::setValue成员函数:

void setValue( const QVariant& v )
{
    if( v != value() )
    {
        //do some stuff
        emit valueChanged();
    }
}
nbnkbykc

nbnkbykc1#

如果你担心潜在的绑定循环,那么将其重写为命令式实现是一个潜在的选择,例如。

CheckBox {
    required property QtObject proxy

    onCheckedChanged: {
        if (proxy && proxy.value !== checked) {
            proxy.value = checked;
        }
    }

    property bool proxyValue: proxy && proxy.value ? true : false

    onProxyValueChanged: {
        if (checked !== proxyValue) {
            checked = proxyValue;
        }
    }
}
bwntbbo3

bwntbbo32#

您的第一个版本在技术上也可能是绑定循环,但不会被检测到。
您希望将复选框值绑定到代理值,并且当用户切换复选框时,您希望修改代理值。
为了避免绑定循环,请为每个组件使用特定的交互信号,而不是通用的onChanged信号。前者只在用户与UI交互时触发,后者每次都会触发,即使更改来自后端更改,也会导致潜在的绑定循环。在您的情况下,您需要toggled信号:

//MyCheckBox.qml

CheckBox {
  required property QtObject proxy
  checked: proxy.value
  onToggled: proxy.value = checked
}

请注意,这仅适用于QQC2,因为当用户切换复选框时,它们不会破坏checked: proxy.value绑定,但仍更改checked属性值,希望最终解决问题。

相关问题