Search code examples
qtdebuggingqstringqdebug

Can you configure QDebug to automatically output with text formatting, and insert info such as the datatypes or namespaces it is returning?


QString m_BoatProgramming("Boat Programming");
qDebug() << m_BoatProgramming;
qDebug() << QDate::currentDate();

Gives me:

"Boat Programming"
"Saturday 20th, 2016"

In some circumstances, rather than going through all the trouble of finding the terminal formatting codes, and manually putting in the metadata, I'd like it to output this:

QStringm_BoatProgramming:"Boat Programming"
QDate::currentDate():"Saturday 20th, 2016"

Is this already possible, or do I need to derive a class from qDebug() ?


Solution

  • Yes it'is possible with message handler. Also it's allow you to write message to files of whatever you need.

    Here is a modified example from doc to match your requirements:

    #include <QApplication>
    #include <stdio.h>
    #include <stdlib.h>
    #include <typeinfo>
    
    #include <QDebug>
    
    void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
    {
        QByteArray localMsg = msg.toLocal8Bit();
        switch (type) {
        case QtDebugMsg:
            fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
            break;
        case QtInfoMsg:
            fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
            break;
        case QtWarningMsg:
            fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
            break;
        case QtCriticalMsg:
            fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
            break;
        case QtFatalMsg:
            fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
            abort();
        }
    }
    
    #define MY_DEBUG( exp ) qDebug() << typeid(exp).name() << #exp << exp
    
    int main(int argc, char **argv)
    {
        qInstallMessageHandler(myMessageOutput);
        QApplication app(argc, argv);
    
        QString str = "Shit happens!";
        MY_DEBUG( str );
    
        return 0;
    }
    

    Will output:

    Debug: class QString str "Shit happens!" (..\ProjectorControl\ProjectorControl\main.cpp:56, int __cdecl main(int,char **))
    

    I think with more macro magic or templates you can achieve more convient behaviour.

    Note: Be carefull using this macro: in fact exp will be executed twice.