当前位置: 首页 > ops >正文

2.qt调试日志输出

目录

  • 1.他们是什么?
  • 2.全局日志QDebug
  • 3.模块化日志QLoggingCategory
  • 3.使用案例
  • 4.全局宏开关控制
  • 5.环境变量开关控制
  • 6.使用建议
  • 7.日志重定向

1.他们是什么?

qCDebug 和 qDebug 都是 Qt 提供的日志输出宏,但它们的用途和功能有所不同。

本质上就是一个宏定义来着,调用栈对象的一个接口

#define qDebug QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).debug
#define qInfo QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).info
#define qWarning QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).warning
#define qCritical QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).critical
#define qFatal QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).fatal#if !defined(QT_NO_DEBUG_OUTPUT)
#  define qCDebug(category, ...) \for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).debug(__VA_ARGS__)
#else
#  define qCDebug(category, ...) QT_NO_QDEBUG_MACRO()
#endif#if !defined(QT_NO_INFO_OUTPUT)
#  define qCInfo(category, ...) \for (bool qt_category_enabled = category().isInfoEnabled(); qt_category_enabled; qt_category_enabled = false) \QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).info(__VA_ARGS__)
#else
#  define qCInfo(category, ...) QT_NO_QDEBUG_MACRO()
#endif#if !defined(QT_NO_WARNING_OUTPUT)
#  define qCWarning(category, ...) \for (bool qt_category_enabled = category().isWarningEnabled(); qt_category_enabled; qt_category_enabled = false) \QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).warning(__VA_ARGS__)
#else
#  define qCWarning(category, ...) QT_NO_QDEBUG_MACRO()
#endif#define qCCritical(category, ...) \for (bool qt_category_enabled = category().isCriticalEnabled(); qt_category_enabled; qt_category_enabled = false) \QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).critical(__VA_ARGS__)

2.全局日志QDebug

不设置QLoggingCategory 输出的就是全局日志

#include <QDebug>  //引入头文件

他们有不同的输出等级

qDebug()<< “qDebug”; //调试信息
qWarning()<< “qWarning”; //警告信息
qInfo()<<“qInfo”; //普通信息
qCritical()<< “qCritical”; //错误信息
//qFatal()<<“qFatal”; //致命错误,终止程序

3.模块化日志QLoggingCategory

Q_LOGGING_CATEGORY(myCategory, “my.module”); //创建一个分类对象
使用qDebug可以不传,但是qCDebug必须传入分类对象

  #include <QLoggingCategory>Q_LOGGING_CATEGORY(myCategory, "my.module");
qCDebug(myCategory)
qCInfo(myCategory)
qCWarning(myCategory)
qCCritical(myCategory)
#include <QLoggingCategory>
Q_LOGGING_CATEGORY(myCategory, "my.module");
QString successText(){qWarning()<< "123123";return "4444";
}int main(int argc, char *argv[])
{qCDebug(myCategory)<< successText();qCDebug(myCategory)<< successText();    //无损耗
}

根据输出结果可以发现输出有个前缀my.module

这样子我们开发插件或者模块 就可以通过此方法
知道是那部分代码输出的日志

在这里插入图片描述

3.使用案例

#include "widget.h"
#include <QDebug>
#include <QLoggingCategory>#include <QApplication>
// Q_DECLARE_LOGGING_CATEGORY(myAppCore)
Q_LOGGING_CATEGORY(myAppCore, "myapp.core")QString logstr()
{qWarning()<< "qWarning";qInfo()<<"qInfo";qCritical()<< "qCritical";return "222";
}int main(int argc, char *argv[])
{qCDebug(myAppCore)<< logstr(); //模块化日志qDebug()<< logstr();QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

4.全局宏开关控制

通过工程文件中设置日志禁用宏

编译器会优化掉日志代码,​零运行时开销。

意思就是使用案例中logstr()函数是不会执行的
无论是qCDebug还是qDebug都会被优化掉,无损耗

    qDebug()<< logstr();

DEFINES += QT_NO_DEBUG_OUTPUT
DEFINES += QT_NO_INFO_OUTPUT
DEFINES += QT_NO_WARNING_OUTPUT

5.环境变量开关控制

无需重新编译​:修改后直接重启应用即可生效。
​灵活控制​:可针对不同模块、不同日志级别(Debug/Info/Warning等)单独开关。

qDebug还是会执行案例中logstr,有损耗
qCDbug设置禁用后,是会被替换成空操作

# 关闭 "myapp.core" 分类的所有日志
export QT_LOGGING_RULES="myapp.core.*=false"# 仅关闭 "myapp.network" 的 debug 日志,保留其他级别
export QT_LOGGING_RULES="myapp.network.debug=false"# 同时控制多个分类
export QT_LOGGING_RULES="myapp.core.debug=false; myapp.network.warning=true"

6.使用建议

​发布版本​:结合编译期禁用(QT_NO_DEBUG_OUTPUT)彻底移除日志开销。
​开发阶段​:使用运行时禁用,灵活调试不同模块的日志。
如果需要动态控制输出,优先使用qCDebug进行日志输出,性能更好

7.日志重定向

可结合 QtMessageHandler 自定义处理函数

QtMessageHandler qInstallMessageHandler(QtMessageHandler);

#include <QApplication>
#include <QFile>
#include <QTextStream>void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {// 自定义处理逻辑(示例:写入文件 + 控制台)QFile logFile("app_log.txt");if (logFile.open(QIODevice::WriteOnly | QIODevice::Append)) {QTextStream stream(&logFile);stream << "[" << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << "] "<< msg << "\n";}// 可选:同时输出到标准错误(控制台)QTextStream(stderr) << msg << "\n";
}int main(int argc, char *argv[]) {qInstallMessageHandler(myMessageHandler); // 注册自定义处理器//qInstallMessageHandler(nullptr); // 恢复默认处理器QApplication app(argc, argv);qDebug() << "This is a debug message";   // 会被 myMessageHandler 处理qCritical() << "Something went wrong!"; // 同上return app.exec();
}
http://www.xdnf.cn/news/16419.html

相关文章:

  • 《C++》STL--string详解(上)
  • vue3报错:this.$refs.** undefined
  • 在Podman/Docker容器中为Luckfox Lyra Zero W编译SDK:终极排错指南
  • Linux实战:从零搭建基于LNMP+NFS+DNS的WordPress博客系统
  • yolo11分类一键训练工具免安装环境windows版使用教程
  • 小白成长之路-Ansible自动化(一)
  • 20250707-2-Kubernetes 网络-Ingress暴露应用(http与https)_笔记
  • LeetCode 60:排列序列
  • 10.模块与包:站在巨人的肩膀上
  • MySQL ROUTER安装部署
  • 网络配置实验报告:主机间通信配置
  • python---eval函数
  • Day44 Java数组08 冒泡排序
  • 51核和ARM核单片机OTA实战解析(二)
  • day062-监控告警方式与Grafana优雅展示
  • 【通识】设计模式
  • Ashampoo Background Remover(照片去背景工具) v2.0.2 免费版
  • MyBatis-Plus IService 接口全量方法实现与测试(续)
  • 【Python系列】从内存分析到性能剖析
  • 【c++】从 “勉强能用” 到 “真正好用”:中文问答系统的 200 行关键优化——关于我用AI编写了一个聊天机器人……(16)
  • HBuilder X打包发布微信小程序
  • 详解力扣高频SQL50题之180. 连续出现的数字【困难】
  • Product Hunt 每日热榜 | 2025-07-27
  • 如何思考一个动态规划问题需要几个状态?
  • J2EE模式---服务层模式
  • springboot基于Java与MySQL库的健身俱乐部管理系统设计与实现
  • 【前后端】node mock.js+json-server
  • vscode找不到python解释器的解决方案
  • listen() 函数详解
  • Petalinux驱动开发