Qt 5.7 QML 为啥我的 CheckBox 属性绑定消失了?

Posted

技术标签:

【中文标题】Qt 5.7 QML 为啥我的 CheckBox 属性绑定消失了?【英文标题】: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
        
    

看起来像这样:

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

谢谢。

【问题讨论】:

【参考方案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; 从而覆盖您的条件。 是的,你是对的,当然。它是通过实际点击完成的。感谢您的澄清。

以上是关于Qt 5.7 QML 为啥我的 CheckBox 属性绑定消失了?的主要内容,如果未能解决你的问题,请参考以下文章

如何使“真正透明”的窗口成为光标,最好是在纯 QML 上? (Qt 5.7)

【QML】复选框 CheckBox

为啥我不能使用我的 QML 单例模块?

Qt5.8 QML 为啥只读的 Controls2.TextArea 有 ibeam 光标?

为啥 Qt 框架不是很流行

Qt-Qml:将复选框绑定到 QAbstractListModel