Frameworks/Porting To qCDebug

From KDE Community Wiki

Introduction

In KDE 4 we had kDebug, kNotice and kWarning. Those were in a categorized fashion which allowed you to set which application should print its debug statements to the console. That was done with "kdebugdialog"

In KDE 5 we didn't have such a thing. We decided to move to Qt5 as much as possible and that meant - initially - to sacrifice kDebug and friends with qDebug and friends. As you might know, qDebug doesn't have category support and no way to get something like kdebugdialog working.

Recently things changed. Upstream Qt has merged categorized versions of qDebug and friends under the name qC<debug/warning/error/..> which does allow categories to be used in debug statements. This wiki page describes how far Qt is with that compared to kDebug and what you should do when porting something.

qCDebug in Qt 5.2

Qt 5.2 is the first version that will make it possible to have categorized debugging. That is very nice and is getting really close to our needs to have a true kDebug replacement. However, it isn't there quite yet. Even when using Qt 5.2 it's still not possible to get the features from kDebug back, most specifically kdebugdialog-like support. It is far enough to strongly recommend you to port kDebug lines to qCDebug lines. More on that down below in the porting section.

qCDebug in Qt 5.3

In Qt 5.3, logging can be configured by either setting rules in the QT_LOGGING_RULES environment variable, or providing a configuration file via the QT_LOGGING_CONF environment variable. See logging rules in the Qt documentation for more information.

Actual porting: kDebug to qCDebug

When porting a library the previous rule was to port kDebug lines to commented qDebug lines (commented to prevent all the noise from showing up on your console). That is now being changed. You should port kDebug lines to qCDebug. To do that you need to include QLoggingCategory. The debug lines will also change slightly. Below is an example of how it looked in kdirlister.cpp and how it should look after porting:

Before porting

kDebug(7004) << "Some long debug message";

After porting

qCDebug(KDIRLISTER) << "Some long debug message";

You probably see the KDIRLISTER define and wonder where that came from. Nowhere, you have to set it. It's the group. To set that the Qt documentation has this example:

// in a header
Q_DECLARE_LOGGING_CATEGORY(KDIRLISTER)

// in one source file
Q_LOGGING_CATEGORY(KDIRLISTER, "kdirlister")

Note that category names should not contain spaces, but can use dots for namespacing, like

 Q_LOGGING_CATEGORY(KDIRLISTER, "qt.driver.usb")

The above won't show you any log lines by default! This is because you've set a custom category (just like we want) and now we need to tell the QCategoryLogger to enable that category. To do so you need to temporarily place the following line somewhere in your code (main function would be nice):

QLoggingCategory::setFilterRules(QStringLiteral("kdirlister.debug = true"));

Note the format of the string:

<category>[.<type>] = true|false

In Qt 5.3 this should not be needed for KDE anymore because we should then be able to manage the logging categories from outside your application. Right now that's not possible so the above line will help you out but will have to be removed once KDE manages the categories. Obviously non KDE applications would still need the above line if you want to show logging output.

More information can be found in this techbase tutorial.