Skip to content

KDAB contributions to Qt 5.9

Qt 5.9 has just been released!

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 to this 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:

void MyTest::testMakeDouble_data() {
    QTest::addColumn<int>("input");
    QTest::addColumn<int>("output");

    QTest::newRow("data01") << 2 << 4;
    QTest::newRow("data02") << 3 << 6;
    QTest::newRow("data03") << 4 << 8;
    // ...
}

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 name
int 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 results
static const auto matcher = qMakeStaticByteArrayMatcher("substring");

// use it multiple times
QByteArray ba = ...;
const int index = matcher.indexIn(ba);

See this blog post for more details.

Other contributions

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 a pressAndHoldInterval 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.

In the meanwhile, grab Qt 5.9 while it’s hot!

About KDAB

KDAB is a consulting company offering a wide variety of expert services in Qt, C++ and 3D/OpenGL and providing training courses in:

KDAB believes that it is critical for our business to contribute to the Qt framework and C++ thinking, to keep pushing these technologies forward to ensure they remain competitive.

Categories: C++ / KDAB Blogs / KDAB on Qt / QML / Qt / Qt3D

Leave a Reply

Your email address will not be published. Required fields are marked *