【问题标题】:Qt 5.7 QML Why are my CheckBox property bindings disappearing?Qt 5.7 QML 为什么我的 CheckBox 属性绑定消失了?
【发布时间】:2016-08-05 22:15:42
【问题描述】:

我有一个简单的CheckBoxes 列表,一周中的每一天都有一个。它们取决于days 的值,一个使用掩码的整数,每个CheckBox 1 位。

使用“全部清除”按钮或“全部设置”按钮都可以分配给days,并且它们会更新。但是,一旦单击任何框,它们将不再响应依赖属性 days 中的更改。

这是为什么?他们是否以某种方式变得不受约束。如果是这样,我是否应该手动重新绑定它们,如果是,为什么?

这是代码,

import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3

ApplicationWindow
{
    visible: true
    width: 800
    height: 400

    property int days: 0

    ColumnLayout
    {
        Repeater
        {
            model: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
            CheckBox
            {
                text: modelData
                checked: (days & (1<<index)) != false
                onClicked:
                {
                    if (checked) days |= (1<<index);
                    else days &= ~(1<<index);
                }

            }
        }

        Button 
        {
            text: "clear all"
            onClicked: days = 0
        }

        Button 
        {
            text: "set all"
            onClicked: days = 127
        }
    }
}

看起来像这样:

要重现问题,首先单击“全部设置”和“全部清除”。然后点击一些复选框。然后再次单击“全部设置”和“全部清除”。您会看到您选中的框不再受到影响。

谢谢。

【问题讨论】:

    标签: qt qml qtquickcontrols


    【解决方案1】:

    在这里。

    Selbie 的回答非常正确。但我想发布一个我喜欢的变体。

    我得出的结论是CheckBoxes 在 QT 中被破坏了。这是因为您希望将它们绑定到您的数据模型。 您还想点击它们(否则有什么意义)。单击它们会断开与模型的连接,因此必须手动修复它(参见 Selbie 的回答)。对我来说,这是一个糟糕的设计。

    我的变体使用Binding,这样您就不必每次点击都重新建立它。

    像这样:

    import QtQuick 2.7
    import QtQuick.Controls 1.4
    import QtQuick.Layouts 1.3
    
    ApplicationWindow
    {
        visible: true
        width: 800
        height: 400
    
        property int days: 0
    
        ColumnLayout
        {
            Repeater
            {
                model: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
                CheckBox
                {
                    text: modelData
                    Binding on checked { value: (days & (1 << index)) != 0 }
                    onClicked:
                    {
                        if (checked) days |= (1<<index)
                        else days &= ~(1<<index)
                    }
                }
            }
    
            Button 
            {
                text: "clear all"
                onClicked: days = 0
            }
    
            Button 
            {
                text: "set all"
                onClicked: days = 127
            }
        }
    }
    

    发布此变体以造福他人。

    【讨论】:

      【解决方案2】:

      当您手动单击复选框时,checked 属性将重新分配给硬编码的true,而不是原始表达式:(days &amp; (1&lt;&lt;index)) != false。同样,手动取消选中该框会强制 checked 属性为硬编码的 false

      解决方法是使用Qt.binding 简单地重新绑定checked 属性。我已经清理了你的 javascript 并修复了你的错误。不客气。

          Repeater
          {
              model: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
              CheckBox
              {
                  function isChecked() {
                      return ((days & (1 << index)) != 0);
                  }
      
                  text: modelData
                  checked: isChecked()
                  onClicked:
                  {
                      if (checked) {
                          days |= (1<<index);
                      }
                      else {
                          days &= ~(1<<index);
                      }
      
                      // now rebind the item's checked property
                      checked = Qt.binding(isChecked);
      
                  }
              }
          }
      

      【讨论】:

      • 非常感谢!你的回答很有效。我没有意识到分配给days 会导致checked 的依赖关系被破坏。谢谢你的解释。
      • 分配给days 不会导致checked 属性被破坏。实际用户单击复选框会导致它被破坏。像这样想。在调用onClicked 之前,Qt 调用checked=true; 从而覆盖您的条件。
      • 是的,你是对的,当然。它是通过实际点击完成的。感谢您的澄清。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-24
      • 2021-05-13
      • 1970-01-01
      • 2011-09-29
      • 2013-09-09
      • 1970-01-01
      相关资源
      最近更新 更多