Qt之QDebug日志输出(含源码)
文章目录
- 一、日志输出示例
- 1.Qt帮助示例源码
- 2.纯净日志输出(日志内容所见即所得)
- 3.Qt格式化输出Qt输出栏(输出至Qt输出栏,不包括文件)
- 4.Qt格式化输出到文件
- 二、日志文件输出的相关理解
- 1.Qt日志输出函数参数分析
- 2.qInstallMessageHandler函数理解
- 3.qSetMessagePattern函数理解
- 4.qFormatLogMessage函数理解
- 三、源码
- main.cpp
- mainwindow
一、日志输出示例
1.Qt帮助示例源码
Qt帮助示例源码,自定义输出格式(通过传入的QMessageLogContext对象获取相关信息),但并未输出文件。
2.纯净日志输出(日志内容所见即所得)
输出函数传入的什么值则把什么值写入到日志文件中。
3.Qt格式化输出Qt输出栏(输出至Qt输出栏,不包括文件)
使用qSetMessagePattern格式化输出内容,并将输出值写入至日志文件中。
4.Qt格式化输出到文件
使用qSetMessagePattern函数定义格式,并使用qFormatLogMessage函数格式化输出值写入文件中。
二、日志文件输出的相关理解
1.Qt日志输出函数参数分析
下方是日志输出程序的函数格式,参数分别是消息类型、消息上下文信息、消息原数据
void myMessageOutput(**QtMsgType type**, **const QMessageLogContext &context**, **const QString &msg**)
- QtMsgType type:消息类型,可根据传入的类型数据通过判断做出不同操作,以下是类型枚举。
enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtInfoMsg, QtSystemMsg = QtCriticalMsg }
- const QMessageLogContext &context:输出数据上下文信息,该对象包含输出数据的版本、输出行号、输出函数名、输出文件名、输出类别(此处类别值得不是QtMsgType的类型)。
- const QString &msg:输出函数的实际输出数据。
2.qInstallMessageHandler函数理解
指定日志输出函数(安装消息处理程序),指定的日志函数参数格式参考Qt日志输出函数参数分析
3.qSetMessagePattern函数理解
设置输出数据格式(设置消息模式),但仅限于输出到“应用程序输出”窗口中,如使用了qInstallMessageHandler,传入输出函数的数据依旧是原内容。
- Qt示例格式串解析
// Qt示例格式串 #define QT_MESSAGE_PATTERN "[%{time yyyyMMdd h:mm:ss.zzz t}%{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}]""%{file}:%{line} - %{message}"
%{time yyyyMMdd h:mm:ss.zzz t}:时间格式化信息,以当前时间为准,该格式输出数据示例“20240503 12:40:36.989 中国标准时间”。
%{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}:根据输出类型输出不同的数据信息。
%{file}:输出数据的实际文件名
%{line}:输出数据的实际行号
%{message}:输出数据的原数据
- Qt自带的参数占位符
占位符 释义 %{appname} 应用程序名称,受pro文件中的TARGET和QApplication::setApplicationName(优先级更高)的影响 %{category} 日志类别 %{file} 输出调用的文件名 %{function} 输出调用的所在函数 %{line} 输出调用的所在行 %{message} 输出实际信息 %{pid} 输出进程的pid(QCoreApplication::applicationPid()) %{threadid} 输出线程的线程id %{qthreadptr} 输出线程的线程指针(QThread::currentThread()的结果) %{type} 输出类型:warning debug info critical fatal %{time process} 进程运行的时间(自进程启动以来的秒数) %{time boot} 计算机Boot启动时间的时间戳(ms) %{time [format]} 时间信息(带格式化信息) %{backtrace [depth=N] } 暂略:此扩展仅在某些平台上可用(目前仅在使用glibc的平台上可用) 4.qFormatLogMessage函数理解
格式化日志信息, 根据qSetMessagePattern函数定义的规则格式化传入的日志信息,建议在qInstallMessageHandler指定的日志输出函数中使用
三、源码
main.cpp
#include "mainwindow.h" #include #include #include #include #define TYPE_FLAG 1 #if 1 == TYPE_FLAG #define OUTPUT_QT_HELP_EXAMPLE // Qt帮助示例输出 #elif 2 == TYPE_FLAG #define OUTPUT_PURE_EXAMPLE // 纯净输出(不夹带任何格式,日志所见即所得) #elif 3 == TYPE_FLAG #define OUTPUT_FORMAT_QT_EXAMPLE // 格式化输出到Qt程序输出栏中 #elif 4 == TYPE_FLAG #define OUTPUT_FORMAT_FILE_EXAMPLE // 格式化输出到指定输出文件中 #endif QString g_fileName; #define QT_MESSAGE_PATTERN "[%{time yyyyMMdd h:mm:ss.zzz t}%{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}]""%{file}:%{line} - %{message}" //! Qt帮助示例源码 void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg); //! 纯净输出 void myMessageOutputForPure(QtMsgType type, const QMessageLogContext &context, const QString &msg); //! 格式输出到Qt程序输出栏 void myMessageOutputForQtConsole(QtMsgType type, const QMessageLogContext &context, const QString &msg); //! 格式输出到指定文件中 void myMessageOutputForFile(QtMsgType type, const QMessageLogContext &context, const QString &msg); int main(int argc, char *argv[]) { #ifdef OUTPUT_QT_HELP_EXAMPLE //! Qt帮助示例输出 // 指定日志输出函数(安装消息处理程序) qInstallMessageHandler(myMessageOutput); #elif defined(OUTPUT_PURE_EXAMPLE) //! 纯净输出(不夹带任何格式,日志所见即所得) g_fileName = "myMessageOutputForPure.log"; // 指定日志输出函数(安装消息处理程序) qInstallMessageHandler(myMessageOutputForPure); #elif defined(OUTPUT_FORMAT_QT_EXAMPLE) //! 格式化输出到Qt程序输出栏中 g_fileName = "myMessageOutputForQtConsole.log"; // 设置输出数据格式(设置消息模式) qSetMessagePattern(QT_MESSAGE_PATTERN); // 指定日志输出函数(安装消息处理程序) qInstallMessageHandler(myMessageOutputForQtConsole); #elif defined(OUTPUT_FORMAT_FILE_EXAMPLE) //! 格式化输出到指定输出文件中 g_fileName = "myMessageOutputForFile.log"; // 设置输出数据格式(设置消息模式) qSetMessagePattern(QT_MESSAGE_PATTERN); // 指定日志输出函数(安装消息处理程序) qInstallMessageHandler(myMessageOutputForFile); #endif QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } 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 %s)\n", localMsg.constData(), file, context.line, function, context.category); break; case QtInfoMsg: fprintf(stderr, "Info: %s (%s:%u, %s %s)\n", localMsg.constData(), file, context.line, function, context.category); break; case QtWarningMsg: fprintf(stderr, "Warning: %s (%s:%u, %s %s)\n", localMsg.constData(), file, context.line, function, context.category); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s (%s:%u, %s %s)\n", localMsg.constData(), file, context.line, function, context.category); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s (%s:%u, %s %s)\n", localMsg.constData(), file, context.line, function, context.category); break; } } void myMessageOutputForPure(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QByteArray localMsg = msg.toLocal8Bit(); QFile file(g_fileName); if(file.open(QIODevice::Append)) { file.write(localMsg + "\n\n"); file.close(); } } void myMessageOutputForQtConsole(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QByteArray localMsg = msg.toLocal8Bit(); QFile file(g_fileName); if(file.open(QIODevice::Append)) { file.write(localMsg + "\n\n"); file.close(); } } void myMessageOutputForFile(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QFile file(g_fileName); if(file.open(QIODevice::Append)) { file.write(qFormatLogMessage(type, context, msg).toLocal8Bit() + "\n\n"); file.close(); } }
mainwindow
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: /** * @brief on_btnQDebug_clicked 调试信息 */ void on_btnQDebug_clicked(); /** * @brief on_btnQInfo_clicked 普通信息 */ void on_btnQInfo_clicked(); /** * @brief on_btnQWarning_clicked 一般警告 */ void on_btnQWarning_clicked(); /** * @brief on_btnQCritical_clicked 严重错误 */ void on_btnQCritical_clicked(); /** * @brief on_btnQFatal_clicked 致命错误 */ void on_btnQFatal_clicked(); /** * @brief on_btnCancelOutputFile_clicked取消输出文件 */ void on_btnCancelOutputFile_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_btnQDebug_clicked() { static int cntFlag = 0; qDebug() static int cntFlag = 0; qInfo() static int cntFlag = 0; qWarning() static int cntFlag = 0; qCritical() static int cntFlag = 0; qFatal(QString(u8"致命错误输出 qFatal %1").arg(++cntFlag).toStdString().data() ) ; } void MainWindow::on_btnCancelOutputFile_clicked() { qInstallMessageHandler(Q_NULLPTR); ui-btnCancelOutputFile-setEnabled(false); }