topic logo
Qt ⇢ Unit 11

Checkboxes

multiple choice selections

Summary

A checkbox is a non-exclusive state button that can be checked and unchecked.

Background

This unit continues to introduce basic widget types that the Qt framework offers. This time it’s the check box, which is the third standard button type.

New Classes

  • QCheckBox: A check box is one of the three basic button types. It’s similar to QRadioButton in that it can be checked by default, but is different in that it has no exclusive checking state and looks slightly different.

  • QFont: A font object is a set of attributes that can be applied to a text. For example to change the font type, size or make it bold or italic.

The CheckBoxDemo App

Instead of creating an app with two check boxes and be done, this time I combine the radio button from the previous unit and show how to tweak the text on a QLabel. The check boxes will act independently and enable bold and italic styling while the radio buttons will be dependent and align the text left, center, or right.

Changing Label Text Attributes
Changing Label Text Attributes
checkboxdemo.cpp - setup label and controls
myLabel = new QLabel("Change me!");
myLabel->setFrameStyle(QFrame::Plain || QFrame::StyledPanel);
myLabel->setMinimumWidth(400);

auto boldCb = new QCheckBox("Bold");
auto italicCb = new QCheckBox("Italic");

auto leftRb = new QRadioButton("Left");
leftRb->setChecked(true);
auto centerRb = new QRadioButton("Center");
auto rightRb = new QRadioButton("Right");

The application starts by setting the text on the label, painting a frame around it and setting a minimum width. It uses an implicit layout this time that builds on the minimum size of the widgets it consists of. Because the text in the label is to be aligned, it needs some space that exceeds it’s text width, which would normally be it’s minimum size, so the minimum size is forced. The frame is only a decorative element. The label is declared in the header because it needs to be referenced from the slots that the controls trigger.

The constructor goes on by setting up the two check buttons that will enable and disable the bold and italic attribute of the text. These are independent attributes, so I choose to use the check boxes.

The three radio buttons set the adjustment of the text. Because only one adjustment state is possible at any given time, it’s sensible to use radio buttons, which provide exclusive selection. I also check the first button, as an application that has no radio buttons checked on startup looks weird. I do this before any signal is connected, so this does not trigger any slot.

checkboxdemo.cpp - setup layout and add items
auto ctrlLayout = new QVBoxLayout();
auto mainLayout = new QHBoxLayout(this);

mainLayout->addLayout(ctrlLayout);
mainLayout->addWidget(myLabel);

ctrlLayout->addWidget(boldCb);
ctrlLayout->addWidget(italicCb);
ctrlLayout->addWidget(leftRb);
ctrlLayout->addWidget(centerRb);
ctrlLayout->addWidget(rightRb);

After creating the label and controls, I create two layouts. The vertical layout holds the controls and is nested into the main layout, which positions the controls and the label side-by-side.

checkboxdemo.cpp - connect controls to solts
connect(boldCb, &QAbstractButton::clicked,
		this, &CheckBoxDemo::toBold);
connect(italicCb, &QAbstractButton::clicked,
		this, &CheckBoxDemo::toItalic);t
connect(leftRb, &QAbstractButton::clicked,
		this, &CheckBoxDemo::toLeft);
connect(centerRb, &QAbstractButton::clicked,
		this, &CheckBoxDemo::toCenter);
connect(rightRb, &QAbstractButton::clicked,
		this, &CheckBoxDemo::toRight);

The constructor finishes by connecting the clicked signal of all the check boxes and radio buttons. These all inherit the same base class, QAbstractButton, so this class’s signal is used.

checkboxdemo.cpp - check box slots
void CheckBoxDemo::toBold(bool checked)
{
    if (checked) {
        auto font = myLabel->font();
        font.setBold(true);
        myLabel->setFont(font);
    } else {
        auto font = myLabel->font();
        font.setBold(false);
        myLabel->setFont(font);
    }
}

void CheckBoxDemo::toItalic(bool checked)
{
    if (checked) {
        auto font = myLabel->font();
        font.setItalic(true);
        myLabel->setFont(font);
    } else {
        auto font = myLabel->font();
        font.setItalic(false);
        myLabel->setFont(font);
    }
}

The checked signal passes along a bool value that tells if the button is checked or unchecked. Based on the value of this parameter, the check box slots add- or remove the bold/italic font attribute. They do this by first requesting the current font attribute of the label. Then only change the attribute they are responsible for and then re-apply the new font attributes to the label. This way the changes of the two slots don’t interfere.

checkboxdemo.cpp - radio button slots
void CheckBoxDemo::toLeft(bool checked)
{
    if (checked) {
        myLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    }
}

void CheckBoxDemo::toCenter(bool checked)
{
    if (checked) {
        myLabel->setAlignment(Qt::AlignCenter);
    }
}

void CheckBoxDemo::toRight(bool checked)
{
    if (checked) {
        myLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    }
}

The radio button slots are similar, but they only react when the button is checked. In this case, they set the alignment. The label in this example is a bit taller than minimal, as it adjusts to the height of the controls. It is placed at one of the top corners when adjusted left or right. It is put back into the vertical middle by combining this with the vertical center alignment flag.

Because radio buttons are exclusive, it is guaranteed, that another button is selected when one is de-selected. So the else branch is not relevant in these slots and is simply ignored.

Conclusion

This unit demonstrated the third major button type and how to manipulate some of the attributes of a label text. This continues the series of introducing the basic widgets, though combined with examples that spice it up.