关于qt:将两个QML CheckBox一起”绑定”,确保它们的状态始终相同

“Bind” two QML CheckBoxes together, ensuring their states are always identical

我想在GUI的不同页面上创建两个复选框,以使它们在语义上是"相同"复选框-相同的标签,相同的效果。 (在两个页面上都放置它们只是为了方便用户。)

这需要将两个CheckBox QML元素"绑定"在一起,以便一个状态始终由另一个反映,反之亦然。

这等同于这里的要求,除了我使用的是QML / JS而不是JS / JQuery。

我认为将每个复选框的checked状态绑定到某个全局持久属性的幼稚实现会起作用:

1
2
3
4
5
// Global shared state object
pragma Singleton
MySharedState {
    my_feature_on: false
}

然后,在两个单独的页面上,完全相同的CheckBox实例化:

1
2
3
4
5
// Checkbox implementation (on both pages
CheckBox {
    checked: MySharedState.my_feature_on
    onClicked: MySharedState.my_feature_on = checked
}

但是,这是行不通的,因为单击复选框时,它会中断初始的checked绑定。这是预期的行为,而不是错误。

那么如何确保两个复选框始终共享相同的"已检查"状态?

编辑:根据下面的评论,上述实现无需修改即可在Qt Quick Controls 2中使用,该版本随Qt 5.7一起发布,因此此问题仅适用于Qt的早期版本(包括5.6,这是一个"长长期支持"版本。


单击一个复选框后,其checked属性将更改,并且原始的checked: MySharedState.my_feature_on绑定也将被删除。
您需要根据Javascript创建属性绑定,以恢复原始绑定,如J-P Nurmi在链接的错误报告中所述。

为此,您必须使用Qt.binding()

1
2
3
4
5
6
7
CheckBox {
    checked: MySharedState.my_feature_on
    onClicked: { // the checked binding is removed since checked has been changed externally to the binding
        MySharedState.my_feature_on = checked
        checked = Qt.binding(function() {return MySharedState.my_feature_on}); //we restore the checked binding
    }
}


使用Binding类型的双向绑定有效:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import QtQuick 2.5
import QtQuick.Controls 1.0

ApplicationWindow {
    objectName:"window"
    width: 600
    height: 200
    visible: true

    Row {
        CheckBox {
            id: checkBox1
            text:"Check Box 1"
        }

        CheckBox {
            id: checkBox2
            text:"Check Box 2"
        }
    }

    Binding {
        target: checkBox2
        property:"checked"
        value: checkBox1.checked
    }

    Binding {
        target: checkBox1
        property:"checked"
        value: checkBox2.checked
    }
}

尽管我不确定为什么它不抱怨绑定循环。