Всех приветствую, сегодня продолжим обзор наиболее базовых элементов QML - на очереди стоит CheckBox. И снова большинство вопросов связаны с кастомизацией стиля, поэтому обязательно рассмотрим пару-тройку конкретных вариантов реализации.
QML CheckBox. Базовые операции.
Начнем по традиции с пустого Qt Quick проекта, в который добавим исключительно то, что будем рассматривать, то есть CheckBox посередине окна 👍

Все изменения сегодня будут осуществлены в main.qml:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
Window {
width: 320
height: 240
visible: true
title: qsTr("QML CheckBox Review ")
CheckBox {
id: testCheckBox
anchors.centerIn: parent
text: qsTr("To check or not to check...")
}
}
В принципе, обычно взаимодействие с CheckBox заключается в проверке свойства checkState. Возможные значения зависят в свою очередь от свойства tristate. По умолчанию tristate = false, и checkState может принимать значения:
- Qt.Unchecked
- Qt.Checked
Если tristate = true, то спектр вариантов пополняется еще одним:
- Qt.Unchecked
- Qt.PartiallyChecked
- Qt.Checked
Тут все просто и очевидно, но тем не менее небольшой пример. Добавим текстовое поле под CheckBox для отображения его состояния:
Window {
width: 320
height: 240
visible: true
title: qsTr("QML CheckBox Review ")
CheckBox {
id: testCheckBox
anchors.centerIn: parent
text: qsTr("To check or not to check...")
onCheckStateChanged: {
switch (checkState) {
case Qt.Unchecked:
testCheckBoxState.text = "I'm unchecked";
break;
case Qt.PartiallyChecked:
testCheckBoxState.text = "I'm partially checked";
break;
case Qt.Checked:
testCheckBoxState.text = "I'm checked";
break;
default:
break;
}
}
}
Text {
id: testCheckBoxState
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: testCheckBox.bottom
anchors.topMargin: 10
text: qsTr("State")
}
}

Об изменении checkState мы узнаем из обработчика onCheckStateChanged. Без него мы могли спокойно обойтись, просто забросив в Text:
Text {
id: testCheckBoxState
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: testCheckBox.bottom
anchors.topMargin: 10
text: qsTr("State") + " " + testCheckBox.checkState
}
Но ладно, оставим обработчик и изменим tristate:
CheckBox {
id: testCheckBox
anchors.centerIn: parent
tristate: true
// ...............
Результат закономерен:

По сути это скорее справочная информация, поскольку все максимально просто. Так что рассмотрим еще один, менее распространенный, но тем не менее часто использующийся вариант, который, в общем-то, неплохо разобран и в официальной документации.
QML CheckBox. Иерархическая структура.
Кстати здесь будет уже понятно, зачем вообще нужно состояние Qt.PartiallyChecked. Итак, добавим три CheckBox и элемент ButtonGroup. При этом свяжем их друг с другом при помощи свойства ButtonGroup.group каждого из CheckBox:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
Window {
width: 320
height: 240
visible: true
title: qsTr("QML CheckBox Review ")
Column {
id: mainColumn
ButtonGroup {
id: primaryGroup
exclusive: false
}
CheckBox {
text: qsTr("CheckBox 1")
ButtonGroup.group: primaryGroup
}
CheckBox {
text: qsTr("CheckBox 2")
ButtonGroup.group: primaryGroup
}
CheckBox {
text: qsTr("CheckBox 3")
ButtonGroup.group: primaryGroup
}
}
Text {
id: primaryGroupState
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: mainColumn.bottom
anchors.topMargin: 10
text: qsTr("State") + " " + primaryGroup.checkState
}
}
В Text будем выводить состояние ButtonGroup через primaryGroup.checkState. В чем смысл содеянного... А смысл в том, что состояние ButtonGroup будет определяться состояниями всех, добавленных к ней элементов. То есть в данном случае это CheckBox'ы. При этом взаимосвязь следующая:
- Если все CheckBox - unchecked, то и primaryGroup - unchecked.
- Если все CheckBox - checked, то primaryGroup - checked.
- Если часть из CheckBox (но не все) - checked, primaryGroup - partially checked.
Вот такая логика. Проверяем:
