前言
在之前的学习中,我们已经对CheckBox进行了较为详细的了解。我们可以简单认为每一个CheckBox都是可供选择的单选框,它们本身的功能和业务较为独立,但如果希望实现CheckBox之间的互斥选择的话,可以选择使用ButtonGroup,它是一个虚拟的隐式组件,可以管理相关联的按钮组之间的选择状态。
这里先附上连接:
QML学习笔记(三十三)QML的CheckBox
但其实,对于互斥的按钮组,我们可以使用更为适合的组件,那就是RadioButton,区别于CheckBox的正方形勾选框,它是圆形的选择样式,它不需要设置ButtonGroup就可以实现互斥,只需要放在同一个父窗口之内。
另外,只是通过ButtonGroup来关联多个CheckBox的话,通常会有些抽象,增加用户学习成本。这里可以引用GroupBox,它自带标题,像一个盒子一样可以将按钮归类起来。
GroupBox和RadioButton就是本节的学习内容,让我们开始吧。
一、了解GroupBox
查阅帮助文档:
翻译一下:
详细描述
GroupBox用于在一个有标题的视觉框架内将一组逻辑控件布局在一起。GroupBox不提供自己的布局,但要求您定位其内容,例如通过创建RowLayout或ColumnLayout。
声明为GroupBox子级的项目会自动成为GroupBox的contentItem的父级。动态创建的项目需要显式地作为contentItem的父级。
如果GroupBox中只使用了一个项目,它将调整大小以适应其包含项目的隐式大小。这使得它特别适合与布局一起使用。
文档中有一个例子,让我们运行看看:
cpp
GroupBox {
title: qsTr("Synchronize")
ColumnLayout {
anchors.fill: parent
CheckBox { text: qsTr("E-mail") }
CheckBox { text: qsTr("Calendar") }
CheckBox { text: qsTr("Contacts") }
}
}

可以看到,这三个勾选框是相互独立的,GroupBox的作用仅仅是将它们归类在一起,并且注意,我们需要自己实现内部的布局。
帮助文档还有另一段代码:
cpp
GroupBox {
label: CheckBox {
id: checkBox
checked: true
text: qsTr("Synchronize")
}
ColumnLayout {
anchors.fill: parent
enabled: checkBox.checked
CheckBox { text: qsTr("E-mail") }
CheckBox { text: qsTr("Calendar") }
CheckBox { text: qsTr("Contacts") }
}
}

可以看到GroupBox标题旁边出现了勾选框,本质上是添加了一个CheckBox,然后通过它来控制ColumnLayout 也就是所有按钮的使能。这种属于使用上的一种变体。
二、了解RadioButton
查看帮助文档:
翻译一下:
单选按钮显示了一个选项按钮,可以打开(选中)或关闭(未选中)。单选按钮通常用于从一组选项中选择一个选项。
RadioButton从AbstractButton继承其API。例如,您可以使用AbstractButton API设置文本并对点击做出反应。可以使用选中的属性设置单选按钮的状态。
默认情况下,单选按钮是自动独占的。在属于同一父项的单选按钮中,任何时候只能选中一个按钮;选中另一个按钮会自动取消选中之前选中的按钮。对于不共享公共父级的单选按钮,ButtonGroup可用于管理独占性。
RadioDelegate类似于RadioButton,除了它通常在视图中使用。
测试一下提供的例子:
cpp
ColumnLayout {
RadioButton {
checked: true
text: qsTr("First")
}
RadioButton {
text: qsTr("Second")
}
RadioButton {
text: qsTr("Third")
}
}

可以看到,三个RadioButton被一个ColumnLayout 所包裹,它们默认就是互斥的,不需要其他设置。文档也说了,如果多个RadioButton不共享父级,也可以用ButtonGroup来实现互斥的独占性。
这个时候,与其简单用ColumnLayout 来归类,还不如为RadioButton们添加GroupBox来得直观。
三、结合GroupBox和RadioButton
cpp
GroupBox{
title: "Choose bonus"
anchors.horizontalCenter: parent.horizontalCenter
Column{
RadioButton{
text: "Coke"
onCheckedChanged: function(){
if(checked){
console.log("Coke button checked")
}else{
console.log("Coke button not checkde")
}
}
}
RadioButton{
text: "Green Tea"
}
RadioButton{
text: "Ice Cream"
}
}
}

四、总结
需要 多选/开关 → CheckBox;
需要 单选/互斥 → RadioButton + 同一父项 或 ButtonGroup;
GroupBox本质上只是一个容器,通常用于存放CheckBox或RadioButton 。