Introduction to Qt framework

Posted by Alan Sambol Friday, Dec 15, 2017
Qt framework - a C++ cross-platform development framework; source:

Qt is a C++ cross-platform development framework for application, UI & device creation. It enables deploying a single C++ codebase providing common APIs across all supported platforms.

What is Qt framework?

Qt (pronounced cute instead of cue tea) is a de-facto industry standard framework for cross-platform C++. Software written in Qt can be run on various platforms with no change in the underlying codebase, while still being a native application with native capabilities and speed. It is available with both proprietary and open source licences.

Qt vs. standard C++

Qt framework contains reimplementations, cross-platform abstractions and utility classes that make standard C++ much simpler to use. It reimplements various parts of the standard C++ and STL. Here is a list of some standard C++ types and their Qt counterparts:

Qt API syntax looks similar to Java syntax and it provides a lot of member functions for convenience (e.g. contains(), indexOf()...). Qt classes use an efficient COW (copy-on-write) implementation, which allows passing them as arguments with a by-value syntax and by-reference implementation - only a pointer to the object is actually sent, and the data itself is copied only when a function writes to it. Qt classes also have an advantage of usability in other Qt APIs.

Another advantage is the same implementation on all operating systems, unlike STL.

There are other pros and cons to using Qt classes vs STL, but I recommend the rule When in Rome, do as the Romans do. - if you already use Qt as a development framework, use it's APIs - it will make your life easier.

Network programming

For network/socket programming in C++, different operating systems use different APIs: winsock2.h on Windows and sys/socket.h on UNIX systems. Qt offers a nice cross-platform abstraction with some of its lower-level classes: QTcpSocket, QTcpServer, QUdpSocket, as well as high-level classes such as QNetworkRequest, QNetworkReply and QNetworkAccessManager.


Same as for network programming, there are different APIs for different operating systems: CreateThread function on Windows and pthread on UNIX systems. Qt again offers several cross-platform abstractions in the form of QThread, QThreadPool and QRunnable classes and QtConcurrent module. 

Qt vs. Java

Qt and Java both solve the multi-platform problem but in a different way. Java has a slogan: Write once, run anywhere - Java programs run on a virtual machine on any platform at a cost of an added overhead and higher JVM memory consumption compared to native programs. Cross-platform compatibility is achieved at the compiled level. Qt, on the other hand, follows another philosophy: Write once, compile anywhere - cross-platform compatibility is implemented only at the source code level, then the code can be compiled (or cross-compiled) to a native program for any platform without any changes.

QtQuick / QML

QtQuick is a Qt module used for creating modern, fluid and dynamic user interfaces for desktop, embedded and mobile platforms. They can be written in C++ or QML - a declarative scripting language with a syntax similar to JSON / Javascript. The basis of QML is C++ and the rendering is handled from a modern scene graph which has Direct3D, OpenGL, Vulkan and fallback software rendering backends. In a modern QML application, the idea is to write UI and high-level UI and business logic in QML, and low-level implementations in C++. C++ objects can be extended and used in QML and vice-versa.

Here is a snippet of basic QML code, resulting in a Rectangle that changes its colour to red when clicked:

import QtQuick 2.0

Rectangle {
    width: 100; height: 100
    color: "green"

    MouseArea {
        anchors.fill: parent
        onClicked: { parent.color = 'red' }

With its declarative nature, it's very easy to quickly develop rich user interfaces, containing fluid animations and state changes, 2D / 3D elements, web content and much more. There is even a way to stream QtQuick applications to a web browser using WebGL streaming.  Some of the most impressive desktop user experiences were built using QML. One example is Blizzard's launcher:



Qt vs. HTML5

In the world of embedded HMI devices, the two most popular technologies are Qt and HTML5. Qt has published a whitepaper comparing the two technologies in a test where one developer was allocated 160 hours to create a demo application using Qt & QML and the same number of hours to create the same application using HTML5. The developer was experienced with using HTML5 and C++ but had little experience creating user interfaces using Qt and QML.

The Qt application had much better performance and responsiveness, its testing and a debugging process was more straightforward than the HTML5 version (which required testing in different browsers) and supported some features like keyboard and multi-touch out of the box.

The difference in application performance can be seen in this video. Here is an infographic comparing the two technologies.

Qt vs. native mobile apps

Mobile apps need to have a great user experience and smooth animations and QML was essentially designed with this goal in mind. Using declarative design approach is much easier and time-efficient than the traditional mobile design, with fewer lines of code and native performance - just like a regular iOS or Android app. 

There are even frameworks built on top of Qt to make building cross-platform mobile apps easier, like V-Play. Here is a comparison of total lines of code used in a sample PropertyCross demo project: 


One disadvantage of using such an approach is losing a portion of specific platform look and feel, because the used UI elements, animation easings and scrolling speeds aren't 100% matched with native ones, although Qt does offer platform-specific implementations.

IDE & build tools


QtCreator is a cross-platform IDE for creating desktop, embedded and mobile applications. It includes a visual debugger, form designers for QtWidgets and QtQuick, syntax highlighting, autocompletion, QML profilers and everything else any modern IDE should have. It can use any C++ compiler or Qt SDK version. It can also be used as a general C++ IDE, without Qt. Here is a screenshot from the QML designer:



Qmake is the standard build tool for Qt applications. It can be used for any software project, whether it is written in Qt or not. It automates the generation of Makefiles based on a project file (.pro), which is generally much simpler than a Makefile. It can also generate projects for Microsoft Visual Studio. Compared to other build systems used in modern languages, qmake feels outdated. It will probably be deprecated soon but supported for a long time. Here is a short example qmake file:

CONFIG += debug
HEADERS += hello.h
SOURCES += hello.cpp
SOURCES += main.cpp
win32 {
    SOURCES += hellowin.cpp
unix {
    SOURCES += hellounix.cpp


QBS (Qt build suite, pronounced cubes) is a qmake and cmake alternative, and unlike qmake, it doesn't rely on make and doesn't generate any Makefiles, which makes it faster. It uses a QML and JavaScript syntax: 

import qbs 1.0

Application {
    name: "helloworld"
    files: "main.cpp"
    Depends { name: "cpp" }

QObject and signals & slots

The QObject class is the base class of all Qt objects, similar to Object class in Java. Qt object model provides both runtime efficiency of C++ and a high level of flexibility. It uses a Meta-Object Compiler (moc) to generate C++ classes from our headers annotated with Q_OBJECT macros. It allows for run-time type information fetching, for example, class or field names. The central feature of this model is a very powerful mechanism for object communication called signals and slots. A signal can be connected to a slot with connect() method. Every time a signal is emitted, its slot function is invoked. The mechanism is type-safe - the signature of a signal must match the signature of the receiving slot. Other frameworks solve this problem by using the observer pattern and callbacks, however, signals and slots are a much more flexible and intuitive solution. For example, traditional callbacks are always called in the context of the calling thread, and unlike them, slots can be in any thread. Here is an example usage of emitting a signal from a setter:

void Counter::setValue(int value)
    if (value != m_value) {
        m_value = value;
        emit valueChanged(value);

Code for connecting signals to slots is as follows:

   QObject::connect(&c, &Counter::valueChanged, &w, &NetworkManager::sendValue);

Signals can be emitted from both C++ or QML code and connected to slots in C++ or QML, in any combination needed.

Qt 3D

There are a lot of essential and add-on Qt modules (full list here). An honourable mention would be the Qt 3D module. It provides functionality for near-real-time simulation systems with support for 2D and 3D rendering in both Qt C++ and QtQuick applications. It is a graphics engine but it's not trying to compete with game engines like Unity or Unreal Engine - it's more generic and allows for greater flexibility. It provides low-level abstractions over basic OpenGL features, concepts and rendering techniques, like meshes, geometry, shaders, materials, shadows, instanced/deferred rendering... Qt 3D is cleanly separated into modules, called aspects, for example, physics, audio, collision, AI and pathfinding aspects. There are C++ and QML bindings, which allows for easy integration with existing QML applications. A Qt 3D scene can be rendered to a 2D surface and used for regular QtQuick user interface, and vice versa - QtQuick scenes can be used as textures for Qt 3D meshes. Here is a simple example of Qt 3D QML project, which includes two meshes, a camera and a camera controller with only a few lines of QML code.


Qt 3D is built using an architectural pattern called Entity-component-system, which is mostly used in game development. It takes the Composition over inheritance principle to the extreme - every object in a scene is an entity (mesh, shader, camera, vehicle, bullet...). Every entity consists of one or more components which add additional behaviour or functionality. The behaviour of the entities is completely defined at runtime and can also be changed at runtime. This allows for great flexibility and eliminates the problems of deep inheritance hierarchies that are difficult to understand, maintain and extend.


Qt 3D uses a data structure for controlling 3D rendering called the framegraph. While a scenegraph is a description of what to render, a framegraph is a description of how to render it. It enables developers to choose between a simple forward renderer, a deferred renderer or any other rendering technique. It allows for control over when to render transparent objects, z-fill passes, shader pipelines and so on, all using a data-driven description, which can even be modified during runtime.  

Physics-based rendering

An example of a custom rendering framegraph is physics-based rendering technique, which is available as a free code example. Physics-based rendering is a standard rendering technique in modern AAA games, but it is also applicable to many other types of 3D content such as engineering, visualization and modern human-machine interfaces. PBR seeks to render graphics in a way that more accurately models the flow of light in the real world, in contrast to traditional ad hoc lighting models. It improves the visual appearance of the scene and makes it easier for artists to get predictable results. A good intro to PBR can be watched in this talk from QtCon by dr. Sean Harmer. Here is the output of the above code example:




Qt is a framework and an extension of C++ which makes the C++ code much closer to higher level languages like Java, while still being compiled to a native program. It is a whole ecosystem with a wide range of modules, and thanks to its modular architecture and the Qt Lite project, allows for a minimal memory footprint while being deployable as a desktop, embedded or a mobile application.

comments powered by Disqus

news / events / blogs