Qt之QDebug日志输出(含源码)

server/2024/9/24 22:56:08/

文章目录

  • 一、日志输出示例
    • 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**)
  1. QtMsgType type:消息类型,可根据传入的类型数据通过判断做出不同操作,以下是类型枚举。
enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtInfoMsg, QtSystemMsg = QtCriticalMsg }
  1. const QMessageLogContext &context:输出数据上下文信息,该对象包含输出数据的版本、输出行号、输出函数名、输出文件名、输出类别(此处类别值得不是QtMsgType的类型)。
  2. const QString &msg:输出函数的实际输出数据。

2.qInstallMessageHandler函数理解

指定日志输出函数(安装消息处理程序),指定的日志函数参数格式参考Qt日志输出函数参数分析

3.qSetMessagePattern函数理解

设置输出数据格式(设置消息模式),但仅限于输出到“应用程序输出”窗口中,如使用了qInstallMessageHandler,传入输出函数的数据依旧是原内容。

  1. 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}:输出数据的原数据

  1. 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  // 格式化输出到指定输出文件中
#endifQString 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);
#endifQApplication 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_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic: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"?>
<ui version="4.0"><class>MainWindow</class><widget class="QMainWindow" name="MainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>283</width><height>146</height></rect></property><property name="windowTitle"><string>MainWindow</string></property><widget class="QWidget" name="centralwidget"><layout class="QVBoxLayout" name="verticalLayout"><item><widget class="QPushButton" name="btnCancelOutputFile"><property name="text"><string>取消输出输出日志</string></property></widget></item><item><layout class="QGridLayout" name="gridLayout"><item row="0" column="0"><spacer name="horizontalSpacer"><property name="orientation"><enum>Qt::Horizontal</enum></property><property name="sizeHint" stdset="0"><size><width>31</width><height>20</height></size></property></spacer></item><item row="0" column="1" colspan="2"><widget class="QPushButton" name="btnQDebug"><property name="text"><string>QDebug</string></property></widget></item><item row="0" column="3" colspan="2"><widget class="QPushButton" name="btnQInfo"><property name="text"><string>QInfo</string></property></widget></item><item row="0" column="5"><spacer name="horizontalSpacer_2"><property name="orientation"><enum>Qt::Horizontal</enum></property><property name="sizeHint" stdset="0"><size><width>32</width><height>20</height></size></property></spacer></item><item row="1" column="0" colspan="2"><widget class="QPushButton" name="btnQWarning"><property name="text"><string>QWarning</string></property></widget></item><item row="1" column="2" colspan="2"><widget class="QPushButton" name="btnQCritical"><property name="text"><string>QCritical</string></property></widget></item><item row="1" column="4" colspan="2"><widget class="QPushButton" name="btnQFatal"><property name="text"><string>QFatal</string></property></widget></item></layout></item></layout></widget><widget class="QMenuBar" name="menubar"><property name="geometry"><rect><x>0</x><y>0</y><width>283</width><height>23</height></rect></property></widget><widget class="QStatusBar" name="statusbar"/></widget><resources/><connections/>
</ui>

友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 ^o^/)

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


http://www.ppmy.cn/server/36454.html

相关文章

使用 scikit-learn 进行机器学习的基本原理-2

介绍 scikit-learn 估计器对象 每个算法都通过“Estimator”对象在 scikit-learn 中公开。 例如&#xff0c;线性回归是&#xff1a;sklearn.linear_model.LinearRegression 估计器参数&#xff1a;估计器的所有参数都可以在实例化时设置&#xff1a; 拟合数据 让我们用 nump…

Stateflow基础知识笔记

01--Simulink/Stateflow概述 Stateflow是集成于Simulink中的图形化设计与开发工具&#xff0c;主要 用于针对控制系统中的复杂控制逻辑进行建模与仿真&#xff0c;或者说&#xff0c; Stateflow适用于针对事件响应系统进行建模与仿真。 Stateflow必须与Simulink联合使用&#…

搜维尔科技:xsens案例,客户制作的一只可爱的鳄鱼短片

搜维尔科技&#xff1a;xsens案例&#xff0c;客户制作的一只可爱的鳄鱼短片 搜维尔科技&#xff1a;xsens案例&#xff0c;客户制作的一只可爱的鳄鱼短片

基于CLAHE算法的图像增强及评价

摘要&#xff1a; 本研究旨在探讨对比度限制自适应直方图均衡化&#xff08;CLAHE&#xff09;算法在数字图像处理中的应用。CLAHE算法通过在局部区域内进行直方图均衡化&#xff0c;有效地增强了图像的对比度&#xff0c;并在保持图像细节的同时避免了过度增强的问题。本文通过…

融知财经:期货交易所每天公布信息包括哪些?

期货交易所是一个非营利机构&#xff0c;它为交易者提供一个公开、公平、公正的交易场所。虽然它不以盈利为目的&#xff0c;但作为一个财务独立的组织&#xff0c;它会通过会员会费、交易手续费和信息服务等方式实现经济利益。期货交易所每天公布的信息主要包括每日行情、交易…

Baidu Comate:你的智能编码助手,编程效率倍增的秘密武器

Baidu Comate智能编码助手 Baidu Comate 智能编码助手简单介绍安装使用查看Comate插件功能智能代码提示使用飞浆和百度智能小程序进行智能问答使用AutoWork插件实现二次函数图像的生成引用Comate知识库存在的问题结束语 Baidu Comate 智能编码助手简单介绍 Baidu Comate&#x…

使用Three.js开发一个3D案例Demo

使用Three.js开发一个3D案例 最近在找工作&#xff0c;发现好多招聘要求都需要会Three.js&#xff0c;以前接触比较多的是2D开发&#xff0c;也就是平面开发&#xff0c;用到的做多的技术就是d3.js&#xff0c;现在3D开发已经成为了大势所趋&#xff0c;所以就学习下Three.js。…

MATLAB绘制蒸汽压力和温度曲线

蒸汽压力与温度之间的具体关系公式一般采用安托因方程&#xff08;Antoine Equation&#xff09;&#xff0c;用于描述纯物质的蒸汽压与温度之间的关系。安托因方程的一般形式如下&#xff1a; [\log_{10} P A - \frac{B}{C T}] 其中&#xff0c; (P) 是蒸汽压&#xff08…