CheckBox and RadioButtton

Creating QML Controls From Scratch: CheckBox and RadioButton

By Chris Cortopassi

Continuing our QML Controls from Scratch series, this time we'll implement a CheckBox. We'll also get RadioButton almost for free. CheckBox is similar to Button with the exception that it holds checked/unchecked state in the checked property. All QML properties have an associated *Changed signal, so the checkedChanged() signal causes onCheckedChanged to run when the property checked changes.

CheckBox also serves as a radio button if a client sets radio: true, which is all RadioButton.qml does. To get multiple radio buttons to act together in a group, put a RadioButton in a ListView delegate with currentIndex indicating the currently selected radio button (see test.qml below).

Since we're not using Image, we used a check ✓ (hexadecimal 2713) unicode glyph to render the check mark as Text, but you might want to replace with an Image .png asset from your designer. The RadioButton dot is implemented with a Rectangle.

Take a look:

CheckBox.qml

import QtQuick 2.0

Item {
    id: root
   
// public
    property string text:    'text'
    property bool   checked: false
   
    signal clicked(bool checked);   //onClicked:{root.checked = checked;  print('onClicked', checked)}

// private
    property real padding: 0.1    // around rectangle: percent of root.height
    property bool radio:   false  // false: check box, true: radio button
   
    width: 250;  height: 50                         // default size
    opacity: enabled  &&  !mouseArea.pressed? 1: 0.3// disabled/pressed state
     
    Rectangle { // check box (or circle for radio button)
        id: rectangle
       
        height: root.height * (1 - 2 * padding);  width: height // square
        x: padding * root.height
        anchors.verticalCenter: parent.verticalCenter
        border.width: 0.05 * root.height
        radius: (radio? 0.5: 0.2) * height
       
        Text { // check
            visible: checked  &&  !radio
            anchors.centerIn: parent
            text: '\u2713' // CHECK MARK
            font.pixelSize: parent.height
        }
       
        Rectangle { // radio dot
            visible: checked  &&  radio
            color: 'black'
            width: 0.5 * parent.width;  height: width // square
            anchors.centerIn: parent
            radius: 0.5 * width // circle
        }
    }

    Text {
        id: text
       
        text: root.text
        anchors {left: rectangle.right;  verticalCenter: rectangle.verticalCenter;  margins: padding * root.height}
        font.pixelSize: 0.5 * root.height
    }
   
    MouseArea {
        id: mouseArea

        anchors.fill: parent

        onClicked: root.clicked(!checked) // emit
    }
}

RadioButton.qml

import QtQuick 2.0

CheckBox {
    radio: true
}

Test.qml

CheckBox {
    property bool backend: false

    text: 'CheckBox'
    checked:   backend
   
    onClicked: backend = checked
}

ListView { // RadioButton
    id: radioButtons
   
    interactive: false
   
    model: [{text: 'RadioButton 0'}, {text: 'RadioButton 1'}]
   
    delegate: RadioButton {
        text:      modelData.text
        checked:   radioButtons.currentIndex == index // equality

        onClicked: radioButtons.currentIndex  = index // assignment
    }
}

Summary

In this post, we created CheckBox and RadioButton. Next time we'll create Switch. The source code can be downloaded here.

Have a question or want to add to the conversation?

You must be logged in to continue.

Log in Register