先上代码:
#include <QCoreApplication>
#include <QDebug>
#include <stdio.h>
#include <stdlib.h>
FILE *output = NULL;
#if (QT_VERSION <= QT_VERSION_CHECK(5, 0, 0))
/* Qt4版本写法 */
void outputRedirection(QtMsgType type, const char *msg)
{
switch (type) {
case QtDebugMsg:
fprintf(output, "Debug: %s\n", msg);
break;
case QtWarningMsg:
fprintf(output, "Warning: %s\n", msg);
break;
case QtCriticalMsg:
fprintf(output, "Critical: %s\n", msg);
break;
case QtFatalMsg:
fprintf(output, "Fatal: %s\n", msg);
abort();
}
}
#else
/* Qt5版本写法 */
void outputRedirection(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
switch (type) {
case QtDebugMsg:
fprintf(output, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtInfoMsg:
fprintf(output, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtWarningMsg:
fprintf(output, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtCriticalMsg:
fprintf(output, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtFatalMsg:
fprintf(output, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
abort();
}
}
#endif
int main(int argc, char **argv)
{
#if (QT_VERSION <= QT_VERSION_CHECK(5, 0, 0))
output = fopen("output.txt", "a"); //重定向于文件
qInstallMsgHandler(outputRedirection);
#else
// output = stdout; // 重定向于打印输出
output = stderr; // 重定向与错误输出
qInstallMessageHandler(outputRedirection);
#endif
QCoreApplication app(argc, argv);
qDebug()<<"Test Test Test";
if (output)
fclose(output);
return app.exec();
}
这里的调试信息为qDebug(), qWarning(), qCritical(), qFatal()的输出.通过注册回调函数:
qInstallMsgHandler(Qt4版本使用Api);
qInstallMessageHandler(Qt5版本使用Api);
即可重定向(拦截)调试信息.
Qt4版本回调函数可实现输出类型与信息,而通过改变output变量的值可重定向输出到文件,stdout(屏幕)或stderr等.
/* Qt4版本写法 */
void outputRedirection(QtMsgType type, const char *msg)
{
switch (type) {
case QtDebugMsg:
fprintf(output, "Debug: %s\n", msg);
break;
case QtWarningMsg:
fprintf(output, "Warning: %s\n", msg);
break;
case QtCriticalMsg:
fprintf(output, "Critical: %s\n", msg);
break;
case QtFatalMsg:
fprintf(output, "Fatal: %s\n", msg);
abort();
}
}
同理Qt5版本回调函数也一样用法,只是功能更加扩展,可以获取到调试信息的文件名字,打印行,所在执行的函数等信息.
/* Qt5版本写法 */
void outputRedirection(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
switch (type) {
case QtDebugMsg:
fprintf(output, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtInfoMsg:
fprintf(output, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtWarningMsg:
fprintf(output, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtCriticalMsg:
fprintf(output, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtFatalMsg:
fprintf(output, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
abort();
}
}
一般应用在发布release版本后使用该功能,还实现日志等功能.
代码地址:
https://github.com/aeagean/QtOutputRedirection