我在调试输出中使用了很多qDebug() <<语句。有没有什么跨平台的方法可以将调试输出重定向到一个文件中,而不求助于shell脚本?我猜open()和dup2()在Linux中可以完成这项工作,但在Windows中用MinGW编译它是否可以工作?也许有一种Qt方法可以做到这一点?
qDebug() <<
jk9hmnmh1#
您必须使用qInstallMessageHandler函数安装一个消息处理程序,然后,您可以使用QTextStream将 debug 消息写入文件。下面是一个示例:
qInstallMessageHandler
QTextStream
#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(); }
取自qInstallMessageHandler的文档(我只添加了注解):
在上面的示例中,函数myMessageOutput使用了stderr,您可能希望将其替换为其他文件流,或者完全重写该函数!一旦你编写并安装了这个函数,你所有的qDebug(以及qWarning,qCritical等)消息都会被重定向到你在处理程序中写入的文件。
myMessageOutput
stderr
qDebug
qWarning
qCritical
hvvq6cgz2#
从here开始,所有积分都归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); abort(); } 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(); }
fnvucqvd3#
下面是一个挂钩默认消息处理程序的工作示例。谢谢你@罗斯罗杰斯!
// -- 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; }
zed5wv104#
这里是一个跨平台的解决方案,如果应用程序是从Qt Creator运行的,则可以登录到控制台,如果应用程序是作为独立应用程序编译和运行的,则可以登录到debug.log文件。
debug.log
主文件.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
日志格式由QString("%1 %2: %3 (%4)").arg...(用于文件)和fprintf(stderr, "%s %s: %s (%s:%u, %s)\n"...(用于控制台)处理。灵感来源:https://gist.github.com/polovik/10714049。
QString("%1 %2: %3 (%4)").arg...
fprintf(stderr, "%s %s: %s (%s:%u, %s)\n"...
wbrvyc0a5#
好吧,我会说,当你需要将调试输出重定向到stderr之外的任何东西时,你可以考虑使用一些日志工具。如果你觉得你需要一个,我会推荐使用Qxt库中的QxtLogger(“QxtLogger类是一个易于使用、易于扩展的日志工具。")。
Qxt
QxtLogger
ss2ws0br6#
下面是一个简单的、线程安全的惯用Qt示例,用于将日志记录到stderr和文件:
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { static QMutex mutex; QMutexLocker lock(&mutex); static QFile logFile(LOGFILE_LOCATION); static bool logFileIsOpen = logFile.open(QIODevice::Append | QIODevice::Text); std::cerr << qPrintable(qFormatLogMessage(type, context, message)) << std::endl; if (logFileIsOpen) { logFile.write(qFormatLogMessage(type, context, message).toUtf8() + '\n'); logFile.flush(); } }
按照其他答案中的说明,使用qInstallMessageHandler(messageHandler)安装它。
qInstallMessageHandler(messageHandler)
6条答案
按热度按时间jk9hmnmh1#
您必须使用
qInstallMessageHandler
函数安装一个消息处理程序,然后,您可以使用QTextStream
将 debug 消息写入文件。下面是一个示例:取自
qInstallMessageHandler
的文档(我只添加了注解):在上面的示例中,函数
myMessageOutput
使用了stderr
,您可能希望将其替换为其他文件流,或者完全重写该函数!一旦你编写并安装了这个函数,你所有的
qDebug
(以及qWarning
,qCritical
等)消息都会被重定向到你在处理程序中写入的文件。hvvq6cgz2#
从here开始,所有积分都归spirit。
fnvucqvd3#
下面是一个挂钩默认消息处理程序的工作示例。
谢谢你@罗斯罗杰斯!
zed5wv104#
这里是一个跨平台的解决方案,如果应用程序是从Qt Creator运行的,则可以登录到控制台,如果应用程序是作为独立应用程序编译和运行的,则可以登录到
debug.log
文件。主文件.cpp:
日志格式由
QString("%1 %2: %3 (%4)").arg...
(用于文件)和fprintf(stderr, "%s %s: %s (%s:%u, %s)\n"...
(用于控制台)处理。灵感来源:https://gist.github.com/polovik/10714049。
wbrvyc0a5#
好吧,我会说,当你需要将调试输出重定向到stderr之外的任何东西时,你可以考虑使用一些日志工具。如果你觉得你需要一个,我会推荐使用
Qxt
库中的QxtLogger
(“QxtLogger类是一个易于使用、易于扩展的日志工具。")。ss2ws0br6#
下面是一个简单的、线程安全的惯用Qt示例,用于将日志记录到
stderr
和文件:按照其他答案中的说明,使用
qInstallMessageHandler(messageHandler)
安装它。