Qt之QDebug日志输出(含源码)
lw向北. 2024-08-21 09:05:03 阅读 93
文章目录
一、日志输出示例1.Qt帮助示例源码2.纯净日志输出(日志内容所见即所得)3.Qt格式化输出Qt输出栏(输出至Qt输出栏,不包括文件)4.Qt格式化输出到文件
二、日志文件输出的相关理解1.Qt日志输出函数参数分析2.qInstallMessageHandler函数理解3.qSetMessagePattern函数理解4.qFormatLogMessage函数理解
三、源码main.cppmainwindow
一、日志输出示例
1.Qt帮助示例源码
Qt帮助示例源码,自定义输出格式(通过传入的QMessageLogContext对象获取相关信息),但并未输出文件。
2.纯净日志输出(日志内容所见即所得)
输出函数传入的什么值则把什么值写入到日志文件中。
3.Qt格式化输出Qt输出栏(输出至Qt输出栏,不包括文件)
使用qSetMessagePattern格式化输出内容,并将输出值写入至日志文件中。
4.Qt格式化输出到文件
使用qSetMessagePattern函数定义格式,并使用qFormatLogMessage函数格式化输出值写入文件中。
二、日志文件输出的相关理解
1.Qt日志输出函数参数分析
下方是日志输出程序的函数格式,参数分别是消息类型、消息上下文信息、消息原数据
<code>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 <QApplication>
#include <QDebug>
#include <QFile>
#include <qlogging.h>
#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 <QMainWindow>
#include <QDebug>
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 <QDebug>
#include <QElapsedTimer>
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() << u8"调试信息输出 qDebug" << ++cntFlag;
}
void MainWindow::on_btnQInfo_clicked()
{
static int cntFlag = 0;
qInfo() << u8"普通信息输出 qInfo" << ++cntFlag;
}
void MainWindow::on_btnQWarning_clicked()
{
static int cntFlag = 0;
qWarning() << u8"一般警告输出 qWarning" << ++cntFlag;
}
void MainWindow::on_btnQCritical_clicked()
{
static int cntFlag = 0;
qCritical() << u8"严重错误输出 qCritical" << ++cntFlag;
}
void MainWindow::on_btnQFatal_clicked()
{
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);
}
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>code>
<ui version="4.0">code>
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">code>
<property name="geometry">code>
<rect>
<x>0</x>
<y>0</y>
<width>283</width>
<height>146</height>
</rect>
</property>
<property name="windowTitle">code>
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">code>
<layout class="QVBoxLayout" name="verticalLayout">code>
<item>
<widget class="QPushButton" name="btnCancelOutputFile">code>
<property name="text">code>
<string>取消输出输出日志</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">code>
<item row="0" column="0">code>
<spacer name="horizontalSpacer">code>
<property name="orientation">code>
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">code>
<size>
<width>31</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1" colspan="2">code>
<widget class="QPushButton" name="btnQDebug">code>
<property name="text">code>
<string>QDebug</string>
</property>
</widget>
</item>
<item row="0" column="3" colspan="2">code>
<widget class="QPushButton" name="btnQInfo">code>
<property name="text">code>
<string>QInfo</string>
</property>
</widget>
</item>
<item row="0" column="5">code>
<spacer name="horizontalSpacer_2">code>
<property name="orientation">code>
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">code>
<size>
<width>32</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2">code>
<widget class="QPushButton" name="btnQWarning">code>
<property name="text">code>
<string>QWarning</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">code>
<widget class="QPushButton" name="btnQCritical">code>
<property name="text">code>
<string>QCritical</string>
</property>
</widget>
</item>
<item row="1" column="4" colspan="2">code>
<widget class="QPushButton" name="btnQFatal">code>
<property name="text">code>
<string>QFatal</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">code>
<property name="geometry">code>
<rect>
<x>0</x>
<y>0</y>
<width>283</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>code>
</widget>
<resources/>
<connections/>
</ui>
友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 ^o^/)
注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。