Qt qInstallMessageHandler详解
引言
qInstallMessageHandler
用于安装自定义的消息处理程序,返回指向上一个消息处理程序的指针 (此函数在Qt 5.0中被引入):
- 函数原型:QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)
这个函数允许码农完全控制Qt库中产生的警告、错误等消息的输出,改变Qt库的默认行为,对于调试应用程序,或者记录应用程序的运行过程非常有用。调用qInstallMessageHandler(0)
,将会恢复Qt默认的消息处理程序。
相比QsLog、Log4Qt等第三方库简单,容易上手,功能复杂建议直接学习第三方日志库,无需重复造轮子。
一、官方例子及参数详解
1.1 Qt默认的消息处理
- 输出
#include <QCoreApplication>
#include <stdio.h>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug("123"); // 无需#include <QDebug>
qDebug() <<"123"; // <<需#include <QDebug>
qWarning("123");
return a.exec();
}
1.2 官方qInstallMessageHandler例程
- 输出:
#include <QCoreApplication>
#include <stdio.h>
#include <QDebug>
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("123"); // 无需#include <QDebug>
qDebug() <<"123"; // 需#include <QDebug>
qWarning("123");
return a.exec();
}
1.3 参数详解
- QtMsgType 枚举类型,描述消息的类别。
常量 | 值 | 对应函数 |
---|---|---|
<QtGlobal>::QtDebugMsg | 0 | qDebug() |
<QtGlobal>::QtInfoMsg (Qt 5.5中加入) | 4 | qInfo() |
<QtGlobal>::QtWarningMsg | 1 | qWarning() |
<QtGlobal>::QtCriticalMsg | 2 | qCritical() |
<QtGlobal>::QtFatalMsg | 3 | qFatal() |
<QtGlobal>::QtSystemMsg | QtCriticalMsg | 和QtCriticalMsg一样 |
- QMessageLogContext 类,提供一些附加信息。
该类提供调用qDebug()、qInfo()、qWarning()等函数时源代码的位置信息。默认情况下,此信息仅记录在Debug版本中,Release版本为空。可以通过定义QT_MESSAGELOGCONTEXT 或 QT_NO_MESSAGELOGCONTEXT 明确覆盖默认设定,决定是否提供源代码位置
。
例如在pro文件中增加定义:DEFINES += QT_MESSAGELOGCONTEXT
C语言中预定义宏 __FILE__、__LINE__、__func__也可输出相同内容,可参考:
C语言中的__FILE__、__LINE__和__func__等预定义跟踪调试
C/C++ 宏定义__FILE__、__LINE__、__func__、__TIME__ 等
- QString 就是一个QString类,存放消息内容。
二、增加打印信息
增加时间的打印,并且更换内容顺序
2.1 效果
2.2 代码
#include <QCoreApplication>
#include <stdio.h>
#include <QString>
#include <QDateTime>
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 : "";
// ----
QString TypeMsg = "";
switch (type) {
case QtDebugMsg:
TypeMsg = QString("Debug");
break;
case QtInfoMsg:
TypeMsg = QString("Info");
break;
case QtWarningMsg:
TypeMsg = QString("Warning");
break;
case QtCriticalMsg:
TypeMsg = QString("Critical");
break;
case QtFatalMsg:
TypeMsg = QString("Fatal");
break;
}
QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss:");
QString OutMsg = time + QString("%1 (%2:%3, %4) ").arg(TypeMsg).arg(file).arg(context.line).arg(function) + localMsg + "\n";
fprintf(stderr, OutMsg.toLocal8Bit().constData());
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qInstallMessageHandler(myMessageOutput);
qDebug("123");
qWarning("123");
qCritical("123");
return a.exec();
}
三、重定向至文件
3.1 效果
3.2 代码
#include <QCoreApplication>
#include <stdio.h>
#include <QString>
#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 : "";
// ----
QString TypeMsg = "";
switch (type) {
case QtDebugMsg:
TypeMsg = QString("Debug");
break;
case QtInfoMsg:
TypeMsg = QString("Info");
break;
case QtWarningMsg:
TypeMsg = QString("Warning");
break;
case QtCriticalMsg:
TypeMsg = QString("Critical");
break;
case QtFatalMsg:
TypeMsg = QString("Fatal");
break;
}
QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss:");
QString OutMsg = time + QString("%1 (%2:%3, %4) ").arg(TypeMsg).arg(file).arg(context.line).arg(function) + localMsg + "\n";
//fprintf(stderr, OutMsg.toLocal8Bit().constData());
// 输出信息至文件中
FILE* f = fopen("log_cs.txt", "a");
fputs(OutMsg.toLocal8Bit().constData(), f);
fclose(f);
f = NULL;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qInstallMessageHandler(myMessageOutput);
qDebug("123");
qWarning("123");
qCritical("123");
return a.exec();
}
参考链接:
Qt5 调试之详细日志文件输出(qInstallMessageHandler):https://www.cnblogs.com/wyuzm/p/9580447.html
C语言文件操作【超详解】:https://blog.csdn.net/qq_55119554/article/details/131750651