DEV Community

Cover image for [Qt] IV. Widgets: QLabel
Misinahaiya
Misinahaiya

Posted on

[Qt] IV. Widgets: QLabel

You have successfully built your first-ever program using Qt. That's amazing, isn't it?

But after you'd come out of excitement, you soon found out that the user interface is way too ugly.

Ugly QLabel

That's not very good. And that's not very Qt. Qt is not a tool for building ugly applications irrespective of whether the app is usable. In simple English, that's not our goal.

How to make it better? Hopefully, it looks like this:

Better QLabel

The label isn't adhered to the margins anymore; instead, it's at the center as a *center widget*. The font weight is bold and mono-spaced to emphasize.

Today, I'll be showing how to beautify the labels.

Widget Basics

This article might be longer than other widget-introducing articles, as I assume you do not know what on earth does the jargon "widget" actually mean, and instead you're just sitting in front of your screen, puzzled, reading my repeatedly use of "widgets," "QWidget, "subclass," etc. in the previous article.

"Subclass" should not be a term that is hard to explain, and I assume you've already known it (sorry for not saying the prerequisite of knowing C++ in the previous articles). Any class inherited a base class is the subclass of the base class.

A "widget," in terms of Qt, is the primary element (the building blocks) for creating GUI. It's the atom of a user interface. Widgets could display data (output), receive user input (input) or as containers of other widgets (process). If you understand how computers work, here are some analogies in the parentheses.

A widget in Qt could also be considered as any object having the base type of QWidget verbatim. The following are all widgets (including the box):

Mini-gallery

As mentioned in the previous article, QWidget that has a parent is called a "widget", whereas parent symbolizes ownership of a widget, as with QObject.

More introductions of various Qt widgets (up two a hundred ones) are on their ways to this series. Stay tuned!

So How Could I Beautiful My Labels!!?

Why are you always so in haste? Don't worry here it is.

Setting text

Before we move on, let's refresh your memory of setting the text of a QLabel. You could do so by using the method QLabel::setText.

Spaces

Alignment

First, we want it to be aligned. Use the method QLabel::setAlignment to do so. To acquire the current alignment, use QLabel::alignment.

Qt is so powerful that it supports the alignment such as:

Qt::AlignmentFlag::AlignLeft:

Align Left

Qt::AlignmentFlag::AlignRight:

Align Right

Qt::AlignmentFlag::AlignHCenter:

Align Horizontal Center

Qt::AlignmentFlag::AlignJustify:

Align Justify

You could also adjust the vertical alignment by using the | operator. For example,

Qt::AlignmentFlag::AlignRight | Qt::AlignmentFlag::AlignTop aligns at the top-right corner:

Align Top and Right

Similarly, Qt::AlignmentFlag::AlignLeft | Qt::AlignmentFlag::AlignBottom aligns at the bottom-left corner:

Align Bottom and Left

Whereas Qt::AlignmentFlag::AlignVCenter aligns as the name suggests:

V-Center

There's a special enumerator: Qt::AlignmentFlag::AlignBaseline. It ensures that the alignment is in accordance with the text baseline in many labels lay outed horizontally instead of the text:

Align baseline

Note that you could use Qt::AlignmentFlag::AlignCenter as Qt::AlignmentFlag::AlignVCenter | Qt::AlignmentFlag::AlignHCenter. They carry the same meaning.

What if I don't want to do alignments?

Indentation

Then, you have indentation. Use QLabel::setIndent to set, and QLabel::indent to acquire the current value.

Note: as you have observed, there are usually two methods: the acquisition method of a specific property of its own name, and the setting method of it using the format of set plus the capitalized name of the property. For example, for alignment, we have setAlignment and alignment. For indent, there are setIndent and indent.

When there's exception, I will tell you. From now on, I call them "properties" and you know the getters and setters, as every character counts in this series.

If alignment is Qt::AlignmentFlag::AlignLeft (the default), then the indentation will be on the left edge, and if alignment is Qt::AlignmentFlag::AlignTop, the indentation will be on the top edge and so on and so forth.

Setting alignment for centers do not have any effect.

Indentation

If both Qt::AlignmentFlag::AlignTop and Qt::AlignmentFlag::AlignLeft or etc. are set, then both vertical and horizontal alignments will be indented:

Indentation advanced

Margins

You could also set the margins using the property margin.

Margins add more space around the label, irrespective of whether the label is indented or aligned or not. The default margin is 0 pixel (it is also counted in pixels).

Precisely, the margin is the distance between the innermost pixel of the label('s border) and the outermost pixel of contents (of the label).

Margins

Wrap

Wait... So, you've just tried out the "justify" example with indentations and margins and all sort of fancy things, but you got this whole long thorn instead of a smaller, (cuter?), fitter version:

Long thorn

You're then looking for the property wordWrap. By using QLabel::setWordWrap(true), you could make the text be wrapped and it should look like this:

Word-wrapped QLabel

Normally, it wrapped according to the size of the window, or the parent widget.

Using HTML

QLabel supports a limited subset of HTML, as well as other editor-like widgets we will cover later. You could just pass in valid and simple HTML code in order to do rich-text formatting.

You could beautiful your text in terms of that.

// I assume you've created your project
// ...
{
    QLabel *label = new QLabel(this);
    setCentralWidget(label);
    label->setAlignment(Qt::AlignmentFlag::AlignCenter);
    label->setMargin(5);
    // label->setIndent(10);
    label->setText("<p style='font-size: 25px;'><b>Beautified</b></p>");
    label->setWordWrap(true);
}
// ...
Enter fullscreen mode Exit fullscreen mode

You could disable it by using the property textFormat. There are four Qt::TextFormat enumerators defined:

Qt::TextFormat::PlainText makes the label displaying plain text:

Plain text

Qt::TextFormat::RichText makes the valid HTML code get parsed and interpreted, as shown as the above example. Also, if you pass in the argument Qt::TextFormat::AutoText, it determines whether if the text is rich text or not by matching the HTML tags. (See function mightBeRichTextImpl in Qt sources). If it is rich text, then Qt::TextFormat::AutoText becomes Qt::TextFormat::RichText. Otherwise, it becomes Qt::TextFormat::PlainText.

You could also add markdown text via Qt::TextFormat::Markdown from version 5.14 on (the latest one is 6.8).

Editable Text

Those are not funny and interesting enough!

Allow me to introduce the final boss: a QLabel could be a simple text editor.

Using the property textInteractionFlags, you could set that:

Qt::TextInteractionFlag::NoTextInteraction:

<a href='https://google.com'>Google</a>
Enter fullscreen mode Exit fullscreen mode

Google

The link seems to be not able to process the hover (mouse-on) events and seems to be disabled, and you could not access so.

To make it accessible, use Qt::TextInteractionFlag::LinksAccessibleByMouse:

Google accessible by mouse

Though it still looks like disabled, you could hover it and see the hyper-link cursor!

To make the keyboard could also access the link via the tab key (called focus, which will be introduced to you later), take the Qt::TextInteractionFlag::LinksAccessibleByKeyboard in bitwise-or operation (|) with LinkAccessibleByMouse:

    label->setTextInteractionFlags(Qt::TextInteractionFlag::LinksAccessibleByKeyboard | Qt::TextInteractionFlag::LinksAccessibleByMouse);
Enter fullscreen mode Exit fullscreen mode

Selectable

If you wish your link is readily available and open in the default browser immediately after activating it (pressing it or clicking Enter, use the property openExternalLinks and set it to true.

It's the same for selection: TextSelectableByMouse by dragging and TextSelectableByKeyboard by using the Shift key(s) and the arrow keys:

<p style='font-weight: 700;'>Lorem ipsum dolor sit amet.<br><a href='https://google.com'>Google</a>
Enter fullscreen mode Exit fullscreen mode
    label->setTextInteractionFlags(Qt::TextInteractionFlag::TextSelectableByMouse | Qt::TextInteractionFlag::TextSelectableByKeyboard | Qt::TextInteractionFlag::LinksAccessibleByKeyboard | Qt::TextInteractionFlag::LinksAccessibleByMouse);
Enter fullscreen mode Exit fullscreen mode

Text Selectable

To investigate whether there is text selected, use the method hasSelectedText. To see the selected text, use the method selectedText.

Finally, the final boss of the final bosses: Qt::TextInteractionFlag::TextEditable. By using this on QLabel, your label could be a mini-text editor:

    label->setTextInteractionFlags(Qt::TextInteractionFlag::TextEditable | Qt::TextInteractionFlag::TextSelectableByMouse | Qt::TextInteractionFlag::TextSelectableByKeyboard | Qt::TextInteractionFlag::LinksAccessibleByKeyboard | Qt::TextInteractionFlag::LinksAccessibleByMouse);
Enter fullscreen mode Exit fullscreen mode

Editable

Now, you know how to beautify your tiny text label!

Top comments (0)