This release marks two important milestones for the Qt Project. The first is that now the Qt 5 series has had more releases than any other Qt version ever (the last release of the Qt 4 series was Qt 4.8). The second milestone is that Qt 5.9 will be a Long Term Support release, therefore providing to many users a stable foundation to build their applications upon.
KDAB has been a significant contributor to this release, as shown by the number of commits by KDAB developers merged into Qt. In this blog post I will showcase some of the most outstanding contributions to Qt 5.9 developed by KDAB engineers.
Commit percentages to Qt in the last 16 weeks, grouped by employer
New features in Qt 3D
The Qt 3D module has seen a lot of improvements in the 5.9 release. Aside from the usual bugfixes, here's some of the most amazing features that Qt 3D gained:
The Scene2D component has been introduced, that allows developers to add a Qt Quick UI inside the 3D scene, including input support:
Two new physics based rendering (PBR) materials have been added, as well as support for image based lighting:
There is now preliminary support for key frame animations, including blend trees between animations. There is also a Python plug-in for Blender that allows artists to export animations curves directly to Qt 3D's JSON format. The Qt 3D animation Easter teaser featured here was made using these technologies.
It is now possible to use level of detail (LOD) for a mesh's geometry.
Support for 2D planar text as well as 3D extruded text has been added:
Please refer tothis guest post on Qt's blog by my colleague Dr. Sean Harmer for more details about these features.
QTest::addRow()
When we create a data-driven test using Qt Test, we need to give a unique name/tag to each data row. This name will then be printed in the test results, and it can be used to conditionally mark a test as an expected failure. For instance, let's take this snippet:
However, sometimes we'd like to generate the input data (and the associated tags) programmatically. Since each row's tag is a mere const char * and not some fancier datatype (such as QString or QByteArray), we need to resort to some convoluted code:
// generates 100 data rows; each one has a unique nameint j =42;for(int i =0; i <100;++i){QTest::newRow(qPrintable(QStringLiteral("data-%1-%2").arg(i).arg(j)))<< i << j;}
Not only is this heavy on the eyes, it's also performing a lot of extra allocations and conversions: for each data entry, a QString temporary needs to be created and then converted into a temporary QByteArray, just in order to pass it as the tag name.
Enter QTest::addRow, new in Qt 5.9: this function adds a new data row for the current test, just like QTest::newRow does. The big difference is that QTest::addRow supports printf-like arguments, avoiding the need of building temporary QStrings and at the same time being much easier to write and understand:
int j =42;for(int i =0; i <100;++i){QTest::addRow("data-%d-%d", i, j)<< i << j;}
QStaticByteArrayMatcher
QStaticByteArrayMatcher is a class added to Qt 5.9 that allows for a fast lookup of a substring in a QByteArray or a const char *. It's a compile-time version of QByteArrayMatcher, in the sense that it leverages C++14 constructs (that is, relaxed constexpr) to build a Boyer-Moore skip table with compile-time data.
If you know that you are going to look multiple times for a certain substring in a byte sequence, you can dramatically optimize the lookup process by leveraging QByteArrayMatcher and QStaticByteArrayMatcher. (There is a QStringMatcher too, for looking into QString-like sequences). For instance:
// build the matcher only once, save the resultsstaticconstauto matcher =qMakeStaticByteArrayMatcher("substring");// use it multiple timesQByteArray ba =...;constint index = matcher.indexIn(ba);
Last, but not least, a few extra features and improvements:
In preparation for QStringView (coming with Qt 5.10), the implementation of QStringLiteral and QByteArrayLiteral has been cleaned up. Starting from Qt 5.9 you can safely assume that a QStringLiteral is always built at compile time; in Qt 5.8 and before there was a fallback to QString::fromUtf8() in certain scenarios. My colleague Marc Mutz blogged about this particular change here.
The QThreadPool::cancel() function, introduced in Qt 5.5, has been deprecated. The function was supposed to give users the ability of removing runnables queued in a QThreadPool, but it had a number of issues: most notably, it was impossible for the user to avoid leaking memory or triggering double deletions. In Qt 5.9 QThreadPool::tryTake() has been introduced in its place, which solves this issue.
In Qt Quick 2, MouseArea now has apressAndHoldInterval property, to allow users to customize the interval after which the pressAndHold signal is emitted (instead of simply using the defaults from the OS).
QHostAddress has been made implicitly shared (surprisingly enough, there are still a few value classes in Qt that are not implicitly shared).
And, finally, a few noteworthy bugfixes:
QMatrix4x4::operator*=() had an aliasing issue: multiplying a matrix by itself would corrupt the result. This has been fixed by properly implementing the operator (to take a copy, and therefore avoiding the aliasing).
Some long standing issues with QDockWidgets have been solved (1, 2, 3, 4).
operator== between QHashes and QMultiHashes has been changed to match C++11 semantics for unordered associative containers: it will now return true if both containers have the same set of (key, value) pairs, without looking at the insertion order.
That's all for now. Stay tuned on this blog for more information about some of these brand new features of Qt 5.9, as well as some new features coming in Qt 5.10.
The KDAB Group is a globally recognized provider for software consulting, development and training, specializing in embedded devices and complex cross-platform desktop applications. In addition to being leading experts in Qt, C++ and 3D technologies for over two decades, KDAB provides deep expertise across the stack, including Linux, Rust and modern UI frameworks. With 100+ employees from 20 countries and offices in Sweden, Germany, USA, France and UK, we serve clients around the world.
Giuseppe D’Angelo
Senior Software Engineer
Senior Software Engineer at KDAB. Giuseppe is a long-time contributor to Qt, having used Qt and C++ since 2000, and is an Approver in the Qt Project. His contributions in Qt range from containers and regular expressions to GUI, Widgets, and OpenGL. A free software passionate and UNIX specialist, before joining KDAB, he organized conferences on opensource around Italy. He holds a BSc in Computer Science.
Our hands-on Modern C++ training courses are designed to quickly familiarize newcomers with the language. They also update professional C++ developers on the latest changes in the language and standard library introduced in recent C++ editions.