Using qDebug

GUI debuggers are the norm these days, however, I still feel the urge to do a little printf-debugging now and then. It might be wrong, it might be silly but it works.

I like to develop the odd graphical application and I like use Qt. For Qt, the nice Norwegian Trolls have provided the qDebug function. You can use it right away just like your old trusted printf:

if(complexStatement(x))
{
    qDebug("This code executes when x = %d", x);
    ...

This works great for integers and other basic types. But, take the fairly common class QColor. Your first thought would probably be to write out each component manually:

qDebug("Color is: %x, %x, %x",
       color.red(),
       color.green(),
       color.blue());

This can be rather tedious, and there are types which are complex to print. For instance, QString, stores unicode strings and uses implicit sharing to reduce copying overhead. This gives you quick internationalized applications, but you cannot easily print the thing. To the rescue: qPrintable.

qDebug("A string: %s", qPrintable(myString));

The qPrintable macro is handy, but you also need to be aware of its quirks. The returned const char pointer is only valid for that very call. I.e. you cannot store it and re-use it - that will most likely give you garbage output.

// Do not do this
const char *text = qPrintable(myString);
// ...
doSomething(text);

For those who refer to printf debugging as cout debugging, and those who like to have a more convenient API, I recommend including the QtDebug header. This way, you can stream most of Qt's types to qDebug. This means a more convenient API for when you need to print QColor values, etc:

qDebug() << color;

Printing using qDebug usually results in console output (you might have to add CONFIG += console to your project file to get output at all on some platforms). However, you can also install a message handler to present your messages in a GUI window, translate them, paint them in colors or just put them in a log file.

______________________

Johan Thelin is a consultant working with Qt, embedded and free
software. On-line, he is known as e8johan.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

need more flexibility

Donno's picture

While I am a BIG fan of QT, I quickly found the built in qDebug too limiting. You could only switch it on or off (no compile-time or run-time levels, and it couldn't write a log file without extra code.

I also looked breifly at other C++ logging libraries and framworks - of particular note, LOG4CPP, which I found much too heavy.

I found a great resource in Dr Dobbs Sept 2007 by Petru Marginean: "Logging in C++".
Logging in C++
Configurable compile-time and run-time levels, easily extended to write to a QT window as well as a log file, stable in multi-threaded apps, easy and light setup and syntax.
Cruising the QT community forums for Logging shows several people advising this simple lib.

-don

Never be ashamed of logging output

TimM's picture

Prinf-debugging has one great advantage over all other forms which is that you can use it in post-mortems. Your users can send you logs which help you reproduce the problem and see how it came about. You can record bits of system state (e.g. environment variables, commandline parameters used to run your program) and so on which are invaluable for finding out what went wrong, especially as people tend to tell white lies about these things sometimes.

If a program is not designed to allow some sort of logging (even as a compile-time option) then it is half-crippled.

Your users can send you logs?

madtom1999's picture

Or, where possible, get the app to send you the info when its in trouble - nothing quite like fixing the problem before your customer complains.
Though make sure your the thing that sends you the email or whatever doesnt turn into a spambot.

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState