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^/)

注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。

注:如有侵权,请联系作者删除



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。