The API of Qt 5 does not differ much from that of Qt 4. Therefore, Qt 5 is almost completely source compatible with its predecessor, which means that we only need a minimal effort to port the existing applications to Qt 5. This section gives a brief introduction to the major changes between versions 4 and 5 of Qt. If you are already familiar with Qt 4, this can serve as a small compendium of what you need to pay attention to if you want to use the features of Qt 5 to their fullest extent.
The biggest change compared to the previous major release of Qt and the one that is immediately visible when we try to build an older application against Qt 5 is that the whole framework was refactored into a different set of modules. Because it expanded over time and became harder to maintain and update for the growing number of platforms that it supported, a decision was made to split the framework into much smaller modules contained in two module groups—Qt Essentials and Qt Add-ons. A major decision relating to the split was that each module could now have its own independent release schedule.
The Essentials group contains modules that are mandatory to implement for every supported platform. This implies that if you are implementing your system using modules from this group only, you can be sure that it can be easily ported to any other platform that Qt supports. Some of the modules are explained as follows:
The QtCore module contains the most basic Qt functionality that all other modules rely on. It provides support for event processing, meta-objects, data I/O, text processing, and threading. It also brings a number of frameworks such as the animation framework, the State Machine framework, and the plugin framework.
The Qt GUI module provides basic cross-platform support to build user interfaces. It is much smaller compared with the same module from Qt 4, as the support for widgets and printing has been moved to separate modules. Qt GUI contains classes that are used to manipulate windows that can be rendered using either the raster engine (by specifying
QSurface::RasterSurfaceas the surface type) or OpenGL (
QSurface::OpenGLSurface). Qt supports desktop OpenGL as well as OpenGL ES 1.1 and 2.0.
The Qt Network module brings support for IPv4 and IPv6 networking using TCP and UDP as well as by controlling the device connectivity state. Compared to Qt 4, this module improves IPv6 support, adds support for opaque SSL keys (such as hardware key devices) and UDP multicast, and assembles MIME multipart messages to be sent over HTTP. It also extends support for DNS lookups.
Qt Multimedia allows programmers to access audio and video hardware (including cameras and FM radio) to record and play multimedia content.
Qt SQL brings a framework that is used to manipulate SQL databases in an abstract way.
Qt WebKit is a port of the WebKit 2 web browser engine to Qt. It provides classes to display and manipulate web content and integrates with your desktop application.
Qt Widgets extends the GUI module with the ability to create a user interface using widgets, such as buttons, edit boxes, labels, data views, dialog boxes, menus, and toolbars that are arranged using a special layout engine. It also contains the implementation of an object-oriented 2D graphics canvas called Graphics View. When porting Qt 4 applications to Qt 5, it is a good idea to start by enabling support of the widgets module (by adding QT += widgets to the project file) and then work your way down from here.
Qt Quick is an extension of Qt GUI, which provides means to create lightweight fluid user interfaces using QML. It is described in more detail later in this chapter as well as in Chapter 9, Qt Quick Basics.
This group contains modules that are optional for any platform. This means that if a particular functionality is not available on some platform or there is nobody willing to spend time working on this functionality for a platform, it will not prevent Qt from supporting this platform.
The largest upgrade to Qt functionality-wise is Qt Quick 2.0. In Qt 4, the framework was implemented on top of Graphics View. This proved to be too slow when used with low-end hardware even with OpenGL ES acceleration enabled. This is because of the way Graphics View renders its content—it iterates all the items in sequence, calculates and sets its transformation matrix, paints the item, recalculates and resets the matrix for the next item, paints it, and so on. Since an item can contain any generic content drawn in an arbitrary order, it requires frequent changes to the GL pipeline, causing major slowdowns.
The new version of Qt Quick instead uses a scene-graph approach. It describes the whole scene as a graph of attributes and well-known operations. To paint the scene, information about the current state of the graph is gathered and the scene is rendered in a more optimal way. For example, it can first draw triangle strips from all items, then render fonts from all items, and so on. Furthermore, since the state of each item is represented by a subgraph, changes to each item can be tracked and it can be decided whether the visual representation of a particular item needs to be updated or not.
QDeclarativeItem class was replaced by
QQuickItem, which has no ties to the Graphics View architecture. There is no routine available where you can directly paint the item, but there is a
QQuickPaintedItem class available that aids in porting old code by rendering content based on
QPainter to a texture and then rendering that texture using a scene-graph. Such items are, however, significantly slower than those directly using the graph approach, so if performance is important, they should be avoided.
In Qt 4, adding signals and slots to a class required the presence of a meta-object (that is, an instance of a class that describes another class) for that class. This was done by subclassing
QObject, adding the
Q_OBJECT macro to it, and declaring signals and slots in special scopes of the class. In Qt 5, this is still possible and advised in many situations, but we now have new interesting possibilities.
It is now acceptable to connect a signal to any compatible member function of a class or any callable entity, such as a standalone function or function object (
functor). A side-effect is a compile-time compatibility check of the signal and the slot (as opposed to the runtime check of the "old" syntax).
In August 2011, ISO approved a new standard for C++, commonly referred to as C++11. It provides a number of optimizations and makes it easier for programmers to create effective code. While you could use C++11 together with Qt 4, it didn't provide any dedicated support for it. This has changed with Qt 5, which is now aware of C++11 and supports many of the constructs introduced by the new version of the language. In this book, we will sometimes use C++11 features in our code. Some compilers have C++11 support enabled by default, in others, you need to enable it. Don't worry if your compiler doesn't support C++11. Each time we use such features, I will make you aware of it.