Forem

Cover image for [Qt] V. Widgets: QPushButton and Buttons
Misinahaiya
Misinahaiya

Posted on

[Qt] V. Widgets: QPushButton and Buttons

"Push me, push me, push me hard"

Some random Japanese anime

Someone who strikes for excellence in a field that he loves

So far, you've gotten something called labels (as in the form of QLabel), and you eagerly want them to obey to your instruction and interact with the user of your tiny, little GUI:

Labeled useless button

You clicked the mouse (or tapped the track-pad, whatever) like a lunatic; "Quit! - The window, now," you demanded. After a fifteen-second combat, you gave up and said, "Qt's so useless! They can't even make the app gone. Let alone those fancy features. I shouldn't 've trusted a !(random guy on dev.to)[https://dev.to/misinahaiya/series/30375) who'd adulated Qt. Be quick, unfollow him! Uninstall Qt now!" And you unfollowed me and uninstalled Qt.

Okay, let's change the timeline. Back before you want to implement a feature with an action of "Quit", you've read my tutorial (specifically, this one). You know you did not learn how to build a responsive widget to response to the user's desires of quitting the application. You just haven't learned them. So, you would not have complained, or uninstalled Qt. (Hopefully you won't have unfollowed me too, by the way) You - sorry for the long prelude - now finally know that you're looking for a widget called a button.

Different Types of Buttons that You'd Better Know

All types of buttons, except for QCommandLinkButton which is an odd one to flatter Windows as well as Microsoft (will be explained later), inherited the subclass of QWidget: the QAbstractButton class. This class encapsulates the common functions of a button, such as displaying the text, drawing the button borders and the icons (if any), setting whether if they could be toggled (and much more, which will all be explained later).

There are totally 4 classes inheriting the QAbstractButton class, so there are totally 5 types of buttons in Qt. Note that the number of types here indicates the number of types of built-in button in Qt. That is, you could draw your own button and handle the event called signals; I'll guide you when you've learned enough. For now, just stick to the five basic buttons (well, you could understand as so), and it should be rather enough.

Checkbox

A checkbox, represented by the class QCheckBox, is just a type of button with a box allowing you to "check" the mark, which is beside the text of the button:

Custom QCheckBox

Actual usage could be found everywhere, for example, in LibreOffice, literally anywhere in every single tab regarding the settings of characters, paragraphs and pages:

LibreOffice's Checkbox

Radio Button

A radio button, represented by the class QRadioButton, is a type of button that is often mutually exclusive under the same parent widget, i.e. only one radio button of a group of radio buttons could be checked at once.

Radio Button

Actual usage could be found also everywhere, particularly in Microsoft Paint:

Paint's Radio Button

Push Button

This class, as represented by the class QPushButton, is - undeniably - the most well-received class among the four; and it is also a part of today's title. The push button is simple, it is just literally a button:

QPushButton

For actual examples... Well, it's way more prevalent than the radio buttons and check buttons, provided how common are the latter ones. Take the simplest one: a single-buttoned message box written in single-line VBScript (Windows only) has a push button (although it isn't that beautiful):

MsgBox("Hi, there's a push button below")
Enter fullscreen mode Exit fullscreen mode

produces

Visual Basic Script push button

Tool Button

We'll talk about it later. Basically, this one - named QToolButton - is just like a flattened push button, almost always with an icon instead of some text, and usually with a "Down" arrow:

QToolButton

This class should be the least common class among the four heirs of the QAbstractButton class, yet we'll still be diving into the QToolButton class later.

Command Link Button

For this one though... As it does not inherit the QAbstractButton class, it is really not that applicable and relevant to today's topic. Many methods will be unavailable.

For introduction, this class is just a mimic of the installers for various applications under the Windows Vista or Windows 7 systems:

Vista

Thanks for StackOverflow for the image.

Since both Windows Vista and Windows 7 are dead now, we'll just skip it. (For people interested though, do dive into this site.)

Customize the buttons

Now let's discover some useful practices you might opt to use when manipulating the buttons, the views or even the whole user interface design. These class are universally (publicly) available among the heirs of the QAbstractButton class. This series makes the QPushButton as the example as it's too common. Note that there will be significant changes in appearance and internal differences of methods of the same name (e.g. setChecked) between the classes.

Automation

Property autoExclusive is one of the features of the radio buttons, as described above. When a group of buttons (that means they have the same parent widget) is checked, then the others must be de-checked. Normally, we don't need this except for a radio button, whose property of autoExclusive is true by default already.

Property autoRepeat is interesting: normally, if you press a button, the button will recognize the click once only. However, with autoRepeat is set to true, the button recognizes the click signal repeatedly after you've clicked (provided you didn't let go) for autoRepeatDelay millisecond, and the interval is autoRepeatInterval millisecond.

Checkability

If we call something "checked", then it is marked by an indicator that is darker (brighter if you're in dark mode) to show that that thing is active, in progress, or any other synonyms. For example, if I'm using ruler in LibreOffice Writer, there will be a brighter box around the action View -> Rulers -> Ruler:

Checked Action

Similarly, if I opt not to show the formatting marks (i.e. invisible characters, will be covered later in the chapter of QTextOption in relation to QTextEdit), there will be no check marks on the action "Formatting Marks (Ctrl+F10)":

Unchecked Action

To make the button checkable, use the property checkable. To see if the button is checked or not or to programmatically set the check state, use the property checked. Normally, radio buttons and check boxes are checkable by default (of course!).

Checked versus unchecked

While we say a radio button or a check box is checked if the indicator (i.e. check mark for check box, circle for radio button) is present instead of the shadings.

Never call setChecked(true) if checkable() == true. Result or behavior is untested or even undefined.

Text

To display some text or retrieve so, use the property text. Simple and intuitive, right?

Simulation

To simulate the user's actions, there's some method to do so programmatically:

  • QAbstractButton::click: when called, the button will instantly recognize itself being clicked. Has no effects when it is disabled.
  • QAbstractButton::animateClick: similar to QAbstractButton::click, but more fancy. It will do some animations to show that the button is clicked. I prefer QAbstractButton::click.
  • QAbstractButton::toggle: just change the check state of the button, but it will not make the button recognize that it has been clicked.

Example

A small example:

// ... Main Windows
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QPushButton *btn = new QPushButton(this);
    btn->setAutoExclusive(false);
    btn->setAutoRepeat(true);
    btn->setAutoRepeatDelay(500);
    btn->setAutoRepeatInterval(300);
    btn->setText("Check me!");
    setCentralWidget(btn);

    // Make the handler of the button,
    // that the function will be called when the button
    // recognizes that it is checked.
    //
    // You'll be introduced in the next chapter.
    connect(btn, &QPushButton::clicked,
            this, &MainWindow::functionToBeCalled);
}

void MainWindow::functionToBeCalled(bool isChecked)
{
    qDebug() << "Clicked!";
    // For your level, just treat this as std::cout.
    // Remember to #include <QDebug>.
}
Enter fullscreen mode Exit fullscreen mode

Result:

Clicked

Have fun with your buttons along with your labels! Next chapter or two (or presumably, more), I'll talk about the most important and well-received Qt feature - signals and slots. Then, we'll be stepping into the realm of layout management (i.e., in plain English, how to cram the labels and buttons and all sort of widgets into a single widget). Stayed tuned!

Top comments (0)