2012-12-20

Yesterday Qt 5.0.0 was released. It is the culmination of huge amounts of work since the announcement of and start of Qt 5′s development. This is the first major release of Qt since the launch of open governance in Autumn 2011, when it became much easier for external individuals and companies to contribute to Qt in terms of code submissions, code reviews, design, and maintenance.

As KDAB benefits from a successful Qt, we have made investments to contribute to the long-term health of the frameworks. There are over 1100 commits from KDAB in the qtbase git repository alone, and many others in other Qt repositories. Excluding individual contributors, we have consistently been the next biggest contributor, second only to the owners of Qt (Nokia/Digia). We have been fixing bugs, implementing wishes from the JIRA tracker, designing writing and testing new features, implementing platform support, reviewing other contributors’ code and participating in discussions around the project.

A new blog series here will detail some of the interesting features of Qt 5.0 which were contributed by KDAB.

QEventLoopLocker

One of the early complete new features contributed by KDAB to Qt 5 was the QEventLoopLocker. This is a class whose need first appeared in KDE, and it relates to the quitOnLastWindowClosed concept in Qt. For KDE applications, there was a desire to quit applications when the last window was closed, but there was also a need to finish some operation before quitting the application. For example, the email with the large attachment is not fully sent yet, or we’re still uploading a large file to an FTP site somewhere. As these operations typically have separate, out-of-process UI, it is ok to not show any window until the job is finished.

That concept was generalized to be able to quit not just the application, but any event loop or any thread, using the new QEventLoopLocker RAII class. This will make implementation of job-queues much easier in Qt 5. For maintenance, the quitOnLastWindowClosed feature in Qt is implemented using the same implementation details as the QEventLoopLocker.

Improved MetaType features

The QMetaType system has seen some large improvements in Qt 5 contributed by KDAB. Some of the improvements were explained at Qt Developer Days in Berlin.

Declaring and using metatypes is now much more convenient in many cases. For example, if you wrote a MyObject type inheriting QObject, or MyWidget type inheriting QWidget in Qt 4, and you wished to put an instance of it into a QVariant, you would need to first use

somewhere in your code. That would allow you to use

In Qt 5, the Q_DECLARE_METATYPE use is no longer needed if your type inherits directly or indirectly from QObject. It is also not needed for any Qt container or smart pointer using types which are themselves metatypes.

For example, these constructs are no longer needed when using Qt 5:

This is also true for types where the user does still have to use Q_DECLARE_METATYPE, for example, when the type does not inherit from QObject:

In some cases in Qt 4, it is also necessary to use the qRegisterMetaType method. The reason to need this is usually that Q_PROPERTY is used with a metatype which is not built-in (types such as int and QString are built-in and don’t need to be marked as metatypes).

With the new possibility of automatically declaring certain types as metatypes, the question of whether we could automatically register them came up too. Because qRegisterMetaType only needs to be used in a small number of cases, most of which relate to QObject or Q_PROPERTY in some way, it was possible to use moc to automatically register types which have not yet been registered. So now, in Qt 5, there are even fewer reasons to have to use qRegisterMetaType.

Another new qRegisterMetaType related feature in Qt 5 is the detection of accidental ODR violations. This often does not have any effect, but can accidentally hide problems such as typos which can mysteriously make your application not work properly. Now, you will get a compile-time or runtime error if using Q_DECLARE_METATYPE and qRegisterMetaType together in a way which has undefined behavior.

Another new feature is the possibility for built-in qobject_cast-style conversion through the inherited types. For example:

This adds features ‘for free’ to domain-specific languages implemented using Qt where the language is based on QObject and properties. It only works for types which inherit from QObject, and can not be generalized for a generic static_cast. The reason for that limitation is that internally it uses the generated QMetaObject of the stored type. Future versions of Qt will extend this feature in a similar way for QSharedPointer conversions.

Another nice but minor feature is that pointers to QObject derived types contained in a QVariant now print out their address and objectName when used with qDebug. For example:

The goals I wrote about elsewhere last year are now met, though the implementation is somewhat different in Qt 5. The SFINAE pattern I wrote about is used extensively to make these features possible.

CMake Config files

For many users of Qt, the CMake buildsystem tool provides advantages over the bundled qmake. Some of the differences compared to qmake were part of a presentation at the recent Qt Developer Days hosted by KDAB in Berlin. Part of the difference in how using CMake will differ when using it with Qt 4 versus Qt 5 is that ‘CMake Config files’ are now generated as part of the build-process of Qt itself and shipped in packages. I previously detailed what that means for users of CMake, and have added new comprehensive documentation to guide new users through the process of using CMake with Qt 5.

Although porting is required when changing from using Qt 4 to Qt 5, simple variable mappings can ease the porting burden.

Show more