qinfo q_assert c++ debugging qt mingw qdebug

c++ - qinfo - q_assert qt



¿Cómo redirigir la salida de qDebug, qWarning, qCritical, etc.? (5)

Estoy usando muchas qDebug() << para la salida de depuración. ¿Hay alguna forma de plataforma cruzada que pueda redirigir esa salida de depuración a un archivo, sin recurrir a scripts de shell? Supongo que open() y dup2() harán el trabajo en Linux, pero ¿funcionará compilado con MinGW en Windows?

Y tal vez hay una forma Qt para hacerlo?


Aquí hay un ejemplo de trabajo de conectar el controlador 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; }


Aquí hay una solución multiplataforma para iniciar sesión en la consola, si la aplicación se ejecutó desde Qt Creator y hasta el archivo debug.log , cuando se compila y se ejecuta 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

El formato del registro lo maneja QString("%1 %2: %3 (%4)").arg... (para el archivo) y fprintf(stderr, "%s %s: %s (%s:%u, %s)/n"... (para la consola).

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


Bueno, yo diría que el momento en que necesitas redirigir tu resultado de depuración a algo diferente de stderr es cuando puedes pensar en alguna herramienta de registro. Si cree que necesita uno, le recomendaría usar QxtLogger ( "La clase QxtLogger es una herramienta de registro fácil de usar y fácil de ampliar" ) de la biblioteca Qxt .


De here todo el crédito va al 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(); }


QTextStream instalar un manejador de mensajes usando la función qInstallMsgHandler y luego, puede usar QTextStream para escribir el mensaje de depuración en un archivo. Aquí hay 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 (solo agregué los comentarios):

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

Una vez que escriba e instale esta función, todos sus qDebug (así como qWarning , qCritical , etc.) se redirigirán al archivo en el que está escribiendo en el controlador.