Qt (WIP)

Purpose

When developing cross-platform, native desktop applications, we typically use the Qt platform.

This article assumes some familiarity with C++.

Learning Material

Qt is divided into a number of modules. For example, the Qt Core, Qt GUI, Qt Widgets, and Qt Quick are all different modules. Review the full list here. The qt modules have different licenses and operating system support, thus it’s important to be aware of what modules you’re using.

Note that, as of writing this module in early 2021, Qt6 is relatively new compared to Qt5. Thus, a lot of online documentation and examples still link to Qt5. Be sure you’re looking at the appropriate documentation for the version of Qt you are using.

These articles provide conceptual basis for working with Qt, either in C++ or using PyQt:

These articles are worth skimming quickly so that you’re aware that they exist when you need them:

Exercises

To learn as much as possible from these exercises, write your responses before revealing the provided answers. If any exercises seem irrelevant, you can skip them and instead write a justification as to why they are unimportant. These justifications will help us improve the lesson for future students.

Exercise 1

What is the difference between the Qt GUI module and the Qt Widgets module? What is the difference between the QGuiApplication and QApplication classes?

Answer

The Qt GUI module is a lower level module:

The Qt GUI module provides classes for windowing system integration, event handling, OpenGL and OpenGL ES integration, 2D graphics, basic imaging, fonts and text. These classes are used internally by Qt’s user interface technologies and can also be used directly, for instance to write applications using low-level OpenGL ES graphics APIs.

For application developers writing user interfaces, Qt provides higher level API’s, like Qt Quick, that are much more suitable than the enablers found in the Qt GUI module.

In particular, the Qt Quick and Qt Widgets modules both build on top of the Qt GUI module.

The QApplication class is the main application class within the Qt Widgets module; it inherits from QGuiApplication.

Exercise 2

What is the difference between Qt Quick and Qt Widgets?

Answer

They are different Qt modules, each building on the Qt GUI module, which allow you to created graphical user interfaces. As a general rule, Qt Widgets are better suited for desktop applications while Qt Quick is better suited for touch applications. You can read a nice comparison, including a feature table, here.

Exercise 3

How are signals and events different from one another?

Exercise 4

What is the difference between a Qt property and a data member? Can any C++ class have Qt property?

Exercise 5

Can you send signals between different threads?

Answer

Yes, using queued connections.

Exercise 6

When you emit a signal, when will its connected slots be invoked?

Answer

It depends on the connection type. If the emitter and receiver live in the same thread, they will typically have a direct connection. Slots with a direct connection will be invoked immediately and in the order in which they were connected. Queued connections, on the other hand, will not be executed until “control returns to the event loop of the receiver’s thread.”

Exercise 7

Is it true that every QObject is associated with a single thread?

Answer

No, although most are. See this part of the QObject page:

A QObject instance is said to have a thread affinity, or that it lives in a certain thread.

When a QObject receives a queued signal or a posted event, the slot or event handler will run in the thread that the object lives in.

If a QObject has no thread affinity (that is, if thread() returns zero), or if it lives in a thread that has no running event loop, then it cannot receive queued signals or posted events.

By default, a QObject lives in the thread in which it is created.

A QObject and it’s children can be moved between threads using QObject::moveToThread.

Exercise 8

Compare Qt Quick to React. In particular, what is the equivalent to the Qt Quick scene graph? (Feel free to skip this question if you’re not familiar with React.)

Answer

The scene graph is like the virtual DOM. In the same way that React determines the minimal number of DOM state changes needed to synchronize the DOM with the virtual DOM, so to does Qt’s scene graph

Exercise 9

Do all Qt C++ classes inherit from QObject? Why or why not?

Answer

No, not all classes do. QObject’s provide new functionality, such as signals and slots, which isn’t always needed. For example, consider the QPoint or the QImage classes; it seems unlikely that you’d want to burden a simple point or image class with any of the features listed in the QObject overview page.

Exercise 10

When you invoke QApplication.exec(), it creates an event loop which runs until the application is closed. Locate where in the qt source code this event loop is created.

The qt documentation is quite good, however, sometimes it is helpful to be able to read the source code.

One purpose of this exercise is to help get you a little familiar with the layout of the Qt source code so that, on a real project, you’ll be more comfortable reaching for this tool when you need it.

Answer

The following answer sketches out one example of the path taken to finding the source code.

First, if you look at the documentation page for QApplication, you’ll notice that it’s in the Qt Widgets module.

The qt source code for several qt modules, including Qt Widgets is found in the qtbase repository.

Within this repository, after some poking around, you’ll find the Qt Widgets code here.

First, I looked in the widgets subdirectory. However, I didn’t see qapplication.h in there. Thus, I eventually found it in the kernel subdirectory here. Here is the implementation of the QApplication.exec method. It’s not too interesting, since it calls the method in QGuiApplication. This is now part of the Qt GUI module. After some searching, I was able to find here. This in turn calls QCoreApplication.exec. After some more searching, I found this here. You can see that the central event loop is constructed and executed here.

I was curious, so I also looked up how the QEventLoop works. The core while loop is here. Pretty cool! This is the heart of all our qt applications.

Continuous Lesson Improvement

Please help us make these lessons as relevant and up-to-date for future engineers as possible!

You can help in several ways:

  • Shorten or clarify the writing. We're all busy and less is more.
  • Ask if the purpose of the lesson is unclear. We want all of the lessons to seem useful.
  • Remove exercises or learning material that aren't useful.
  • Add more exercises, exercise answers, or learning material as appropriate.

You can quickly open the lesson page in the GitHub editor. Create a new branch and pull request and assign it to David.