"Bind" 两个 QML CheckBox 在一起,确保它们的状态始终相同

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

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

这需要 "binding" 两个 CheckBox QML 元素在一起,这样一个的状态总是被另一个反映,反之亦然。

这是 equivalent to what's being asked here,除了我使用 QML/JS 而不是 JS/JQuery。

我认为将每个复选框的 checked 状态绑定到某个全局持久性 属性 的简单实现是可行的:

// Global shared state object
pragma Singleton
MySharedState {
    my_feature_on: false
}

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

// Checkbox implementation (on both pages
CheckBox {
    checked: MySharedState.my_feature_on
    onClicked: MySharedState.my_feature_on = checked
}

但是,这不起作用,因为当单击复选框时,它会破坏初始 checked 绑定。这是 intended behavior, not a bug.

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

编辑: 根据下面的评论,上述实现无需修改即可在 Qt Quick Controls 2 中运行,Qt Quick Controls 2 是随 Qt 5.7 一起发布的,所以这个问题只适用于之前的Qt 版本(包括 5.6,这是一个 "long-term support" 版本)。

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

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

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

当一个复选框被点击时,它的 checked 属性 被改变并且原来的 checked: MySharedState.my_feature_on 绑定被移除。 您需要 create a property binding from Javascript 恢复原始绑定,正如 J-P Nurmi 在您链接的错误报告中所解释的那样。

为此你必须使用 Qt.binding()

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