DEV Community

Cover image for [Qt] III. Hello, World!
Misinahaiya
Misinahaiya

Posted on

[Qt] III. Hello, World!

So you have been forced to sit in front of your computer, looking at the screen for one hour or two, to install the behemoth Qt. Then, you really wanted to try out the best IDE in the universe - Qt Creator, but you were intimidated by the (slightly?) overly posh user interface:

Welcome Screen of Qt Creator

You did not know what to do.

That's normal, as it is the first time that you got to know Qt. Let me introduce how to create your first Qt application.

"Hello, World!" is probably the most iconic and the most well-known programming language example for absolute beginners. So, for Qt, even it is just a comprehensive tool, I will still be introducing you "Hello, World!" as the first example ever for our series.

Projects (Oh My!)

Every app, created or edited on Qt Creator, is called a "project". Don't be misguided by the name, a project need not to be very complex or large.

To create a project, you should select the "File" menu on the top-left corner. Select "Project" to create a new project.

Create Project Action

Then, a dialog called "wizard" will appear. It guides you to create your first project:

Create Project Wizard's Select Project Type

Here, just choose "Application (Qt)", which implies using the C++ programming language. We are not going to use Python or develop web applications in Qt throughout this series, are we? So, leave those fields intact. Click "Choose".

After that, you would see the dialog below:

Create a new project

Name your project a reasonable and clear name. I'll use "Hello World" for this article. Do note that special characters (including spaces ' ' yet not hyphens '-' nor underlines '_') are illegal characters in project names, i.e. you cannot use them in naming your project.

Normally, you do not need to create any folder for your project, as Qt Creator will create it for you. As for me, I prefer put my projects into a directory called "Projects" under the location of the Documents folder. But trust me, changing this will not affect anything. It's just a matter of preference.

If you decide to use this directory continuously and throughout this series (and presumably also continuously for your own app development), remember to check the check box "Use as default project location." It will make Qt Creator recognize your preference.

Click "Next," if there are no problems. Then you'll see a simple yet standard combo-box:

Define Build System

I'm generally against you using qbs, as it's outdated and not maintained for more than 5 years.

You could choose QMake, the own Qt build system for C++. But in this tutorial, I'm going to use CMake, as it is supported by the Qt 6 (the latest version) more than that of Qt 5. In other words, QMake will still be, inevitably, deprecated in the future.

If you really love QMake, there are a lot of useful and official guides online that you could make a reference of. If you do pure Qt, there are no difference between QMake and CMake except the syntax. They both generate Makefiles. But due to the official support and the latter one is more compatible to external tools (e.g. OpenCV uses CMake), I do CMake.

Anyway, let's do away with the page and flick the dialog to the new page:

Create MainWindow file

Now, de-check the "Generate From" check box.

What does that action do? Well, it launches the so-called convenient tool of "Qt Designer", which is already bundled in and bound with Qt Creator. You could just actually craft a good-looking, fancy user interface without any coding involved.

Sounds nice, right? We'll abstain from using this throughout the whole series. Why?

Think about it: athletes are trained with heavy and weary things called "burden" on their backs, and when they do really be in a race, they'll be like running above the sky. Same thing for your Qt odyssey: if you do want to have absolutely no dark corners on how you could craft the user interface and on how to be an architect at user interface, don't use it.

Instead, with my detailed explanations, you'll be very good at building everything from scratch under the Qt framework. After that, you could then try out the Qt Designer.

Parlez-vous Francais

Je suis en train de essayer le Qt Creator!

Ok, we'll not be doing French or other things here, at least for now. Internationalization and translations will be introduced and be there later. Skip them now to be simple. (Well, Qt has a astonishingly meticulous internationalization system. I can't omit the elephant in the room, but to explain it thoroughly you must have a solid foundation on the topics we'll be covering later.)

Select kits

Okay, kits! Well, for kits, my advice is, select the default one. If you just installed one version of Qt (e.g. Qt 6.8.2), on Windows, "MinGW" will then be shown and be the default. On macOS, it should be "clang" or "LLVM". On GNU/Linux and (mostly) the others, it should be "GCC".

If not, I suggest you de-checking the default ones and checking these. The tutorial will be focusing on these compilers respectively; unless you have a solid foundation on those kits, or any other reason that you have to use those kits.

(Note that on Windows, when we reach the point of creating web browsers, "MSVC" must be used instead of "MinGW". I'll explain it why later. Now, just choose "MinGW". In most of the time, it will do)

No-Git day

Well... Here, we aren't going to do Git. If you wish and you have git, you could craft your own repository as well. But that's not for me, due to simplicity.

Click "Finish". Yippee, we're done!

Hello, World!

Note that you could always change almost all the above configurations in the "Project" column on the leftmost bar of the Qt Creator.

Building the Real "Hello, World!"

Let's look at the three source files created:

main.cpp:

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
Enter fullscreen mode Exit fullscreen mode

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
};
#endif // MAINWINDOW_H
Enter fullscreen mode Exit fullscreen mode

mainwindow.cpp:

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
}

MainWindow::~MainWindow()
{
}
Enter fullscreen mode Exit fullscreen mode

Where MainWindow is a subclass of QMainWindow (as suggested by its name), and the latter one is a subclass of QWidget.

Understanding the files

In the main file, the QApplication object is imported and used before the creation of the MainWindow type. That's correct, as there must always be an, and only one, QApplication instance before the creation of any paint-devices. In simple words, any QWidget must be created after the creation of a QApplication.

This is because that QApplication is considered as a coordinator of the different widgets and objects: how should they interact with the user and the system? How should they be arranged? How should handle their lives (e.g. construction and destruction)? A QApplication object is always responsible for these.

By just looking at its methods: setDoubleClickInterval, setCursorFlashTime, setStartDragDistance, setStartDragTime or topLevelWidgets could prove so.

Note that the application object needs to have the arguments as the parameters.

After that, at the MainWindow constructor, you could see a parameter called parent. By practice, if a QWidget does not have a parent, it is the top-level widget (i.e., a window).

If it does have, then we say the ownership of the widget is transferred to its parent widget. It means that the widget becomes the child of its parent, and when the parent got destructed, all of its children also got destructed, even if you had not implemented the destructor method to demand explicitly the program and Qt to destruct the children, for it is applicable for every QObject and its subclasses.

Calling the show method shows the main window (also for any other QWidget). If it is already embedded in another QWidget (and generally it becomes a child), calling this has no use.

Finally, the app should return the value of exec. The method exec indicates it's time for the application to receive user input, so-called "entering the main-loop". It generally returns 0, indicating that no error occurred.

Now, key the shortcut Ctrl and R, or click the menu as follows: Build -> Run. You could see an empty window if your compiler is okay:

Empty Hello World

Where's my Hello World?

Don't be in haste. If you saw an empty window, that indicates you have a good compiler and you're going to do so.

Change the mainwindow.cpp as follows:

#include "mainwindow.h"

#include <QLabel>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QLabel *label = new QLabel(this);
    label->setText("Hello, World!");
    setCentralWidget(label);
}

MainWindow::~MainWindow()
{
}
Enter fullscreen mode Exit fullscreen mode

Tips: Every QObject needs to be in pointer form if they need to interact with other objects. In the above example, label is set as the central widget by another QObject, MainWindow.

We included the QLabel widget. It's another subclass of QWidget that used to display read-only text. If you have any experience in designing GUI, you might have come across similar widgets. For example, in TCL/Tk, you may have Label. In Wx Frameworks, you have wxStaticText. They all mean the approximately same thing.

To set the text, you could just pass the text as strings to the method setText. After that, to make it the central widget (i.e., widget that occupies most of the space of the main window), use the method defined in QMainWindow: setCentralWidget.

Now, build again.

First successful example

Succeed!

Hello, World!
Hello, Qt!
Hello, Everyone!

Top comments (0)