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

2024-05-03 17:20
文章标签 输出 源码 日志 qt qdebug

本文主要是介绍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**)
  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^/)

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

这篇关于Qt之QDebug日志输出(含源码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/957253

相关文章

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

QT Creator配置Kit的实现示例

《QTCreator配置Kit的实现示例》本文主要介绍了使用Qt5.12.12与VS2022时,因MSVC编译器版本不匹配及WindowsSDK缺失导致配置错误的问题解决,感兴趣的可以了解一下... 目录0、背景:qt5.12.12+vs2022一、症状:二、原因:(可以跳过,直奔后面的解决方法)三、解决方

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

java -jar example.jar 产生的日志输出到指定文件的方法

《java-jarexample.jar产生的日志输出到指定文件的方法》这篇文章给大家介绍java-jarexample.jar产生的日志输出到指定文件的方法,本文给大家介绍的非常详细,对大家的... 目录怎么让 Java -jar example.jar 产生的日志输出到指定文件一、方法1:使用重定向1、

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

nginx配置错误日志的实现步骤

《nginx配置错误日志的实现步骤》配置nginx代理过程中,如果出现错误,需要看日志,可以把nginx日志配置出来,以便快速定位日志问题,下面就来介绍一下nginx配置错误日志的实现步骤,感兴趣的可... 目录前言nginx配置错误日志总结前言在配置nginx代理过程中,如果出现错误,需要看日志,可以把

Qt中实现多线程导出数据功能的四种方式小结

《Qt中实现多线程导出数据功能的四种方式小结》在以往的项目开发中,在很多地方用到了多线程,本文将记录下在Qt开发中用到的多线程技术实现方法,以导出指定范围的数字到txt文件为例,展示多线程不同的实现方... 目录前言导出文件的示例工具类QThreadQObject的moveToThread方法实现多线程QC

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用