Qt Tips and Tricks - Part 1
In this blog post, I'll present a few tips and tricks for using Qt of which you may not be aware. These are small topics that I didn't feel justified an entire blog post of their own and were collected by polling the ICS Qt consulting team.
Qt Extras
There are platform-specific features available in the Qt "Extras" modules: Android Extras (1), Mac Extras (2), Win Extras (3) and X11 Extras (4).
While it is always best to avoid platform-specific features whenever possible, these modules allow you to use some features of a specific platform from within Qt, avoiding the need to call the platform APIs directly.
I covered the X11 Extras in a previous blog post (5) when it first came out in the Qt 5.1 release.
QDebug Output Formatting
The QDebug (6) class is handy for producing debug information, typically using the qDebug() method. By default, the function automatically puts spaces between items and outputs a newline at the end, which is usually the desired behavior. It also puts quotation marks around character-type objects like QChar and QString. Since Qt 5.4.0, if you want to suppress the behavior of adding spaces and quotes you can call the methods QDebug::nospace() and QDebug::noquote(). Here is a short but complete, program example illustrating this:
#include <QDebug> #include <QString> int main() { QString foo = "Hello"; int x = 1234; qDebug() << "foo=" << foo << "x=" << x; qDebug().nospace().noquote() << "foo=" << foo << " x=" << x; }
The program produces the output:
foo= "Hello" x= 1234
foo=Hello x=1234
The qDebug() function can display Qt class instances and, as of Qt version 5.5, enumerated types.
QPA Back Ends
Qt supports using various QPA (Qt Platform Abstraction) back ends for rendering. You can specify the back end to use with the -platform command line option when invoking a Qt-based application. You can also specify which back end to use by setting the environment variable QT_QPA_PLATFORM. This can be handy if you always want to use a specific back end and it is not the default compiled into your version of Qt.
One way to see the valid list of platforms in your version of Qt is to specify an invalid -platform option and look at the error output. Here is an example running on a Linux desktop system:
% /usr/local/Qt-5.6.0/examples/widgets/widgets/calculator/calculator -platform foo
This application failed to start because it could not find or load the Qt platform plugin "foo".
Available platform plugins are: directfbegl, directfb, eglfs, linuxfb, minimal, minimalegl, offscreen, wayland-egl, wayland, xcb.
C++11 Support
Recent releases of most C++ compilers support many, if not all features of the C++11 language standard. With some older compilers you need a command line option to enable C++11 support. If you are using qmake as your build system, you can handle this in a portable way by putting this line in your qmake project file:
CONFIG += c++11
There is also a "CONFIG += c++14" option that enables support for the C++14 standard, but you will need a very recent compiler version, such as gcc 5, in order for it to be supported.
Making Run-Time Warnings Fatal
If you want to make sure that any warnings produced by Qt are not ignored at run-time, you can define the environment variable QT_FATAL_WARNINGS.
When this is set, your application will abort when a warning is encountered. This can be either an internal warning produced by Qt (such as an error in signal/slot connections) or a warning in your own application's code triggered by calling qWarning().
While you are unlikely to want to do this in production code shipped to end users, it can be useful during development and testing to catch errors and make them more obvious.
Turning Compile Warnings into Errors
If you want to force compile warnings to be treated as errors, most compilers have an option for this. With the gcc compiler, a suitable option can be enabled by putting this line in your qmake project file:
QMAKE_CXXFLAGS += -Werror
With Microsoft Visual Studio the appropriate compiler option is "/WX". The line below in your qmake project file will set the correct option based on the compiler being used:
*g++*: QMAKE_CXXFLAGS += -Werror
*msvc*: QMAKE_CXXFLAGS += /WX
You may want to do this for builds performed by your continuous integration (CI) system, to catch compile warnings by flagging them as errors and forcing developers to correct them.
Debugging Plugins
When developing or using Qt plugins, you may have problems determining where a plugin is being loaded from or why it is not being loaded. A useful debug technique is to set the QT_DEBUG_PLUGINS environment variable. If this is set to a non-zero value in the environment in which your application is launched, Qt will display diagnostic information about the plugins it attempts to load.
The output is quite long (typically several hundred lines) so I won't show an example here, but I encourage you try it yourself.
Spying on Signals
The QSignalSpy (7) class allows you to connect to any signal from any Qt object and record when it is emitted.
It is most useful when writing tests, such as unit tests for widgets. You may also find it useful when debugging or doing performance testing.
There is a similar QML element, called SignalSpy (8), that works with Qt Quick.
Q_GADGET
The Q_GADGET (9) macro is a lighter weight alternative to Q_OBJECT for classes that don't inherit from QObject, but still want to use some of the reflection capabilities offered by QMetaObject.
Like the Q_OBJECT macro, it must appear in the private section of the class definition. Q_GADGETs can have Q_ENUM, Q_PROPERTY and Q_INVOKABLE qualifiers, but not signals or slots.
The Qt documentation give more details.
Summary
Justin Noel of ICS gave a presentation on "Qt - Tips and Tricks" at the Qt Developer Days conference in 2010 that you may find useful. A video (10) of that talk is available on YouTube. More recently, he gave an introductory talk in a webcast entitled "Got Qt? 10 Things to Know Before You Code", which can be viewed at the ICS website (11).
I hope to continue this series of blog posts with more tips and tricks in the future. If you enjoyed this article, you can continue on with the second blog in this series: Qt Tips and Tricks - Part II
Thanks go to the ICS development team for providing many of the tips and tricks presented here.
References
- Android Extras, Qt documentation website, last accessed November 20 2015, doc.qt.io/qt-5/qtandroidextras-index.html
- Mac Extras, Qt documentation website, last accessed November 20 2015, doc.qt.io/qt-5/qtmacextras-index.html
- Win Extras, Qt documentaton website, last accessed November 20 2015, doc.qt.io/qt-5/qtwinextras-index.html
- X11 Extras, Qt documentation website,last accessed November 20 2015, doc.qt.io/qt-5/qtx11extras-index.html
- What's New in Qt 5.1: X11 Extras, ICS blog post, last accessed November 20 2015, www.ics.com/blog/whats-new-qt-51-x11-extras
- QDebug class, Qt documentation website, last accessed November 20 2015, doc.qt.io/qt-5/qdebug.html
- QSignalSpy class, Qt documentation website, last accessed November 20 2015, doc.qt.io/qt-5/qsignalspy.html
- SignalSpy QML element, Qt documentation website, last accessed November 20 2015, doc.qt.io/qt-5/qml-qttest-signalspy.html
- Q_GADGET macro, Qt documentation website, last accessed November 20 2015, doc.qt.io/qt-5/qobject.html#Q_GADGET
- Qt - Tips and Tricks, Qt Developer Days 2010 presentation by Justin Noel, last accessed November 20 2015, www.youtube.com/watch?v=tG04090zDvA
- Got Qt? 10 Things to Know Before You Code, ICS webinar, last accessed November 20 2015, www.ics.com/webinars/got-qt-10-things-know-you-code