qInstallMessageHandler方法介绍
安装前面定义的Qt消息处理程序。返回指向上一个消息处理程序的指针。
消息处理程序是一个输出调试消息、警告、关键和致命错误消息的函数。Qt库(调试模式)包含数百条警告消息,当内部错误(通常是无效的函数参数)发生时,这些警告消息将被打印出来。在发布模式下构建的Qt也包含这样的警告,除非在编译期间设置了QT_NO_WARNING_OUTPUT和/或QT_NO_DEBUG_OUTPUT。如果实现自己的消息处理程序,则可以完全控制这些消息。
默认消息处理程序将消息打印到X11下的标准输出或Windows下的调试器。如果是致命消息,则应用程序在处理该消息后立即中止。自定义消息处理程序不应试图自行退出应用程序。
只能定义一个消息处理程序,因为这通常是在应用程序范围内完成的,以控制调试输出。
需要恢复消息处理程序,请调用qInstallMessageHandler(0)。
官方例子
#include <stdio.h> #include <stdlib.h> #include <QCoreApplication> #include <QDateTime> #include <QFile> void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QByteArray localMsg = msg.toLocal8Bit(); const char *file = context.file ? context.file : ""; const char *function = context.function ? context.function : ""; switch (type) { case QtDebugMsg: fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtInfoMsg: fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtWarningMsg: fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; } } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 安装消息处理程序 qInstallMessageHandler(myMessageOutput); // 打印信息 qDebug("This is a debug message."); qWarning("This is a warning message."); qCritical("This is a critical message."); qFatal("This is a fatal message."); return a.exec(); }
输出
可以看到,本来只有文本的内容,这里已经多了函数名称、行号·、文件名称。我们可以对日志的输出做一个消息处理。输出一些我们认为重要的信息。
Debug: This is a debug message. (main.cpp:78, int main(int, char**)) Warning: This is a warning message. (main.cpp:79, int main(int, char**)) Critical: This is a critical message. (main.cpp:80, int main(int, char**)) Fatal: This is a fatal message. (main.cpp:81, int main(int, char**)) Press <RETURN> to close this window...
输出日志文件
我们只需要对官方提供的例子稍作改造,由原本的输出,改为写入文件即可。
修改官方例子
// 自定义消息处理程序 void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QString text; switch(type) { case QtInfoMsg: text = QString("[Info\t]"); break; case QtDebugMsg: text = QString("[Debug\t]"); break; case QtWarningMsg: text = QString("[Warning\t]"); break; case QtCriticalMsg: text = QString("[Critical\t]"); break; case QtFatalMsg: text = QString("[Fatal\t]"); } QDateTime current_date_time = QDateTime::currentDateTime(); QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss ddd"); QString message = text.append(current_date).append(" ").append(msg) .append(" file:").append(context.file) .append(" function:").append(context.function) .append(" category:").append(context.category) .append(" line:").append(QString::number(context.line) .append(" version:").append(QString::number(context.version))); QFile file(QString(QDate::currentDate().toString("yyyy-MM-dd") + ".txt")); file.open(QIODevice::WriteOnly | QIODevice::Append); QTextStream text_stream(&file); text_stream<<message<<"\r\n"; file.close(); }
输出的文件
可以看到输出按照日期格式的文件。
控制台和文件均输出
只需要在原本写入文件的位置,增加一行控制台输出即可。就能实现控制台、文件多出输出。
// 自定义消息处理程序 void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QString text; switch(type) { case QtInfoMsg: text = QString("[Info\t]"); break; case QtDebugMsg: text = QString("[Debug\t]"); break; case QtWarningMsg: text = QString("[Warning\t]"); break; case QtCriticalMsg: text = QString("[Critical\t]"); break; case QtFatalMsg: text = QString("[Fatal\t]"); } QDateTime current_date_time = QDateTime::currentDateTime(); QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss ddd"); QString message = text.append(current_date).append(" ").append(msg) .append(" file:").append(context.file) .append(" function:").append(context.function) .append(" category:").append(context.category) .append(" line:").append(QString::number(context.line) .append(" version:").append(QString::number(context.version))); QFile file(QString(QDate::currentDate().toString("yyyy-MM-dd") + ".txt")); file.open(QIODevice::WriteOnly | QIODevice::Append); QTextStream text_stream(&file); qDebug() << message; // 实现控制台、文件多出输出 text_stream<<message<<"\r\n"; file.close(); }
卸载消息处理
需要恢复消息处理程序,调用qInstallMessageHandler(nullptr)即可。
qInstallMessageHandler(nullptr);