2011-02-10 10 views

Respuesta

85

Tienes que instalar un controlador de mensajes usando qInstallMsgHandler función, y luego, se puede utilizar para escribir el QTextStreamdepuración mensaje en un archivo. Este es un ejemplo de muestra:

#include <QtGlobal> 
#include <stdio.h> 
#include <stdlib.h> 

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(); 
    } 
} 

int main(int argc, char **argv) 
{ 
    qInstallMessageHandler(myMessageOutput); // Install the handler 
    QApplication app(argc, argv); 
    ... 
    return app.exec(); 
} 

Tomado del doc de qInstallMsgHandler (I solo añadió los comentarios):

En el ejemplo anterior, la función myMessageOutput utiliza stderr lo cual es posible que desee reemplazar con alguna otra secuencia de archivos, ¡o reescribir completamente la función!

Una vez que escribir e instalar esta función, toda su qDebug (así como qWarning, qCritical etc) los mensajes serán redireccionados al archivo que está escribiendo en el controlador.

+3

Hola, muchas gracias. No solo me permitirá redirigir la salida de depuración a un archivo, también me permite imprimir más información útil, como una marca de tiempo :) – Septagram

+2

@Septagram: Exactamente. Puede agregar algunos mensajes útiles en el propio hanlder; e incluso puede enviar diferentes mensajes a diferentes archivos, en función de lo que use 'qDebug',' qWarning', 'qCritical' ¡y así sucesivamente! – Nawaz

+1

Por cierto, la devolución de llamada que hace la salida real - void myMessageOutput (tipo QtMsgType, const char * msg) - ¿en qué codificación recibe un mensaje? – Septagram

5

Bueno, yo diría que el momento en que necesitas redirigir tu salida de depuración a algo diferente de stderr es cuando puedes pensar en alguna herramienta de registro. Si usted siente que necesita que yo recomendaría el uso de QxtLogger ("La clase QxtLogger es una herramienta fácil de usar, fácil de extender herramienta de registro.") de Qxt biblioteca.

11

De here todo el crédito va a spirit.

#include <QApplication> 
#include <QtDebug> 
#include <QFile> 
#include <QTextStream> 

void myMessageHandler(QtMsgType type, const QMessageLogContext &, const QString & msg) 
{ 
    QString txt; 
    switch (type) { 
    case QtDebugMsg: 
     txt = QString("Debug: %1").arg(msg); 
     break; 
    case QtWarningMsg: 
     txt = QString("Warning: %1").arg(msg); 
    break; 
    case QtCriticalMsg: 
     txt = QString("Critical: %1").arg(msg); 
    break; 
    case QtFatalMsg: 
     txt = QString("Fatal: %1").arg(msg); 
    break; 
    } 
    QFile outFile("log"); 
    outFile.open(QIODevice::WriteOnly | QIODevice::Append); 
    QTextStream ts(&outFile); 
    ts << txt << endl; 
} 

int main(int argc, char * argv[]) 
{ 
    QApplication app(argc, argv); 
    qInstallMessageHandler(myMessageHandler); 
    ... 
    return app.exec(); 
} 
+0

caso QtFatalMsg: ... abort(); // saldrá antes de escribir el registro – raidsan

+0

@raidsan bien capturado! –

+0

Comience desde QT 5,' qInstallMessageHandler' se debe utilizar en lugar de 'qInstallMsgHandler' para cambiar el manejador de mensajes . – SuB

5

Este es un ejemplo de trabajo de enganchar el manejador de mensajes predeterminado.

Gracias @Ross Rogers!

// -- main.cpp 

// Get the default Qt message handler. 
static const QtMessageHandler QT_DEFAULT_MESSAGE_HANDLER = qInstallMessageHandler(0); 

void myCustomMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) 
{ 
    // Handle the messages! 

    // Call the default handler. 
    (*QT_DEFAULT_MESSAGE_HANDLER)(type, context, msg); 
} 

int main(int argc, char *argv[]) 
{ 
    qInstallMessageHandler(myCustomMessageHandler); 

    QApplication a(argc, argv); 

    qDebug() << "Wello Horld!"; 

    return 0; 
} 
2

Aquí es una solución multiplataforma para iniciar la sesión en la consola, si la aplicación se corrió de la Qt Creator y para el archivo debug.log, cuando se compila y se corrió como una aplicación independiente.

main.cpp:

#include <QApplication> 
#include <QtGlobal> 
#include <QtDebug> 
#include <QTextStream> 
#include <QTextCodec> 
#include <QLocale> 
#include <QTime> 
#include <QFile> 

const QString logFilePath = "debug.log"; 
bool logToFile = false; 

void customMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) 
{ 
    QHash<QtMsgType, QString> msgLevelHash({{QtDebugMsg, "Debug"}, {QtInfoMsg, "Info"}, {QtWarningMsg, "Warning"}, {QtCriticalMsg, "Critical"}, {QtFatalMsg, "Fatal"}}); 
    QByteArray localMsg = msg.toLocal8Bit(); 
    QTime time = QTime::currentTime(); 
    QString formattedTime = time.toString("hh:mm:ss.zzz"); 
    QByteArray formattedTimeMsg = formattedTime.toLocal8Bit(); 
    QString logLevelName = msgLevelHash[type]; 
    QByteArray logLevelMsg = logLevelName.toLocal8Bit(); 

    if (logToFile) { 
     QString txt = QString("%1 %2: %3 (%4)").arg(formattedTime, logLevelName, msg, context.file); 
     QFile outFile(logFilePath); 
     outFile.open(QIODevice::WriteOnly | QIODevice::Append); 
     QTextStream ts(&outFile); 
     ts << txt << endl; 
     outFile.close(); 
    } else { 
     fprintf(stderr, "%s %s: %s (%s:%u, %s)\n", formattedTimeMsg.constData(), logLevelMsg.constData(), localMsg.constData(), context.file, context.line, context.function); 
     fflush(stderr); 
    } 

    if (type == QtFatalMsg) 
     abort(); 
} 

int main(int argc, char *argv[]) 
{ 
    QByteArray envVar = qgetenv("QTDIR");  // check if the app is ran in Qt Creator 

    if (envVar.isEmpty()) 
     logToFile = true; 

    qInstallMessageHandler(customMessageOutput); // custom message handler for debugging 

    QApplication a(argc, argv); 
    // ...and the rest of 'main' follows 

formato de registro es manejado por QString("%1 %2: %3 (%4)").arg... (para el archivo) y fprintf(stderr, "%s %s: %s (%s:%u, %s)\n"... (para consola).

Inspiración: https://gist.github.com/polovik/10714049.

Cuestiones relacionadas