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

Qt自定义日志输出

Qt自定义日志输出

简略版:

#include <QApplication>
#include <QDebug>
#include <QDateTime>
#include <QFileInfo>
// 将日志类型转换为字符串
QString typeToString(QtMsgType type) {switch (type) {case QtDebugMsg: return "Debug";case QtInfoMsg: return "Info";case QtWarningMsg: return "Warning";case QtCriticalMsg: return "Critical";case QtFatalMsg: return "Fatal";default: return "Unknown";}
}
void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {// 当前时间,只保留到秒QString timeText = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");// 简化文件名,只显示文件名,不显示路径QString file(context.file ? context.file : "no-file");file = QFileInfo(file).fileName();// 构建简化的日志信息QString formattedMessage = QString("%1 [%2] (%3:%4): %5").arg(timeText).arg(typeToString(type)).arg(file).arg(context.line).arg(msg);// 输出到控制台fprintf(stderr, "%s\n", formattedMessage.toLocal8Bit().constData());
}
int main(int argc, char *argv[]) {QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);qInstallMessageHandler(customMessageHandler);QApplication a(argc, argv);return QApplication::exec();
}

效果图:

在这里插入图片描述

详细版:

#include <QApplication>
#include <QPushButton>
#include <QDebug>
#include "gamepanel.h"
#include <QDateTime>
#include <QFileInfo>void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {// 当前时间QString timeText = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");// 构建日志信息QByteArray localMsg = msg.toLocal8Bit();const char* file = context.file ? context.file : "no-file";const char* function = context.function ? context.function : "no-function";switch (type) {case QtDebugMsg:fprintf(stderr, "%s [Debug] (%s:%u, %s): %s\n", timeText.toLocal8Bit().constData(), file, context.line, function, localMsg.constData());break;case QtInfoMsg:fprintf(stderr, "%s [Info] (%s:%u, %s): %s\n", timeText.toLocal8Bit().constData(), file, context.line, function, localMsg.constData());break;case QtWarningMsg:fprintf(stderr, "%s [Warning] (%s:%u, %s): %s\n", timeText.toLocal8Bit().constData(), file, context.line, function, localMsg.constData());break;case QtCriticalMsg:fprintf(stderr, "%s [Critical] (%s:%u, %s): %s\n", timeText.toLocal8Bit().constData(), file, context.line, function, localMsg.constData());break;case QtFatalMsg:fprintf(stderr, "%s [Fatal] (%s:%u, %s): %s\n", timeText.toLocal8Bit().constData(), file, context.line, function, localMsg.constData());abort(); // 此调用将终止程序}
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 安装日志处理函数qInstallMessageHandler(customMessageHandler);// 生成日志消息qDebug() << "hello,world";return a.exec();
}

效果图

在这里插入图片描述

注意事项:

  • 需要在main函数安装日志处理函数: qInstallMessageHandler(customMessageHandler);,安装这个函数以后,整个项目全局使用,不需要再重新安装

  • 可以再CMakeLists.txt中添加以下设置用于控制日志是否输出,如果不禁止注释掉即可

    add_definitions(-DQT_NO_DEBUG_OUTPUT) //禁用调试输出
    add_definitions(-DQT_NO_INFO_OUTPUT) //禁用信息级别的日志输出
    add_definitions(-DQT_NO_WARNING_OUTPUT) //禁用警告级别的日志输出
    

使用:

以下是详细版的修改版本,只保存主要的信息

我们可以创建一个命名空间用于存放这个自定义日志输出

  • Logger.h
#ifndef MYLANDLARDS_SRC_LOGGER_H
#define MYLANDLARDS_SRC_LOGGER_H#include <QString>
#include <QMessageLogContext>namespace Logger {
void customMessageHandler(QtMsgType type,const QMessageLogContext &context,const QString &msg);
QString typeToString(QtMsgType type);
}#endif //MYLANDLARDS_SRC_LOGGER_H
  • Logger.cpp
#include "Logger.h"
#include <QDateTime>
#include <QFileInfo>
#include <cstdio>namespace Logger {void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {QString timeText = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");QString file = QFileInfo(context.file ? context.file : "no-file").fileName();QString function = context.function ? context.function : "no-function";QString formattedMessage = QString("%1 [%2] (%3:%4, %5): %6").arg(timeText).arg(typeToString(type)).arg(file).arg(context.line).arg(function).arg(msg);fprintf(stderr, "%s\n", formattedMessage.toLocal8Bit().constData());
}QString typeToString(QtMsgType type) {switch (type) {case QtDebugMsg: return "Debug";case QtInfoMsg: return "Info";case QtWarningMsg: return "Warning";case QtCriticalMsg: return "Critical";case QtFatalMsg: return "Fatal";default: return "Unknown";}
}} // namespace Logger
  • main.cpp
#include <QApplication>
#include <QDebug>
#include "Logger.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);qInstallMessageHandler(Logger::customMessageHandler);qDebug() << "hello,world";return QApplication::exec();
}

效果图:

在这里插入图片描述

如果最后需要将日志输出到文件中,可以叫ChatGPT修改即可

相关文章:

Qt自定义日志输出

Qt自定义日志输出 简略版&#xff1a; #include <QApplication> #include <QDebug> #include <QDateTime> #include <QFileInfo> // 将日志类型转换为字符串 QString typeToString(QtMsgType type) {switch (type) {case QtDebugMsg: return "D…...

[C++] vector list 等容器的迭代器失效问题

标题&#xff1a;[C] 容器的迭代器失效问题 水墨不写bug 正文开始&#xff1a; 什么是迭代器&#xff1f; 迭代器是STL提供的六大组件之一&#xff0c;它允许我们访问容器&#xff08;如vector、list、set等&#xff09;中的元素&#xff0c;同时提供一个遍历容器的方法。然而…...

Java——变量作用域和生命周期

一、作用域 1、作用域简介 在Java中&#xff0c;作用域&#xff08;Scope&#xff09;指的是变量、方法和类在代码中的可见性和生命周期。理解作用域有助于编写更清晰、更高效的代码。 2、作用域 块作用域&#xff08;Block Scope&#xff09;&#xff1a; 块作用域是指在…...

WPF界面设计

1、使用C#-WPF实现抽屉效果-炫酷漂亮的侧边栏导航菜单-SplitViewMD主题重绘原生控件的美观效果-提供源码Demo下载 码源地址&#xff1a;https://download.csdn.net/download/Prince999999/89424685 2、使用C#-WPF实现抽屉效果-菜单导航功能实现&#xff0c;常规的管理系统应该…...

【C#】使用JavaScriptSerializer序列化对象

在C#开发语言编程中&#xff0c;通常使用系统内置的JavaScriptSerializer类来序列化对象&#xff0c;以便将其转换为JSON格式的文本存储与后台服务通信, 在这里将为大家详细介绍一下这个过程。 文章目录 反序列化序列化忽略属性 假设处理的数据中有一个对象类, 如下 public cl…...

HTML静态网页成品作业(HTML+CSS)—— 明星吴磊介绍网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…...

EasyRecovery2024数据恢复神器#电脑必备良品

EasyRecovery数据恢复软件&#xff0c;让你的数据重见天日&#xff01; 大家好&#xff01;今天我要给大家种草一个非常实用的软件——EasyRecovery数据恢复软件&#xff01;你是不是也曾经遇到过不小心删除了重要的文件&#xff0c;或者电脑突然崩溃导致数据丢失的尴尬情况呢&…...

前端HTML相关知识

1.什么是HTML HTML 指的是超文本标记语言 ( HyperText Markup Language )。 超文本:是指页面内可以包含图片、链接、声音,视频等内容 标记:标签(通过标记符号来告诉浏览器网页内容该如何显示) 浏览器根据不同的HTML标签&#xff0c;解析成我们看到的网页 2.HTML的特点 HTML不…...

集合面试题

目录 ①HashMap的理解&#xff1f;以及为什么要把链表转换为红黑树&#xff1f;②HashMap的put&#xff1f;③HashMap的扩容&#xff1f;④加载因子为什么是0.75&#xff1f;⑤modcount的作用&#xff1f;⑥HashMap与HashTable的区别&#xff1f;⑥HashMap中1.7和1.8的区别&am…...

集成学习概述

概述 集成学习(Ensemble learning)就是将多个机器学习模型组合起来&#xff0c;共同工作以达到优化算法的目的。具体来讲&#xff0c;集成学习可以通过多个学习器相结合&#xff0c;来获得比单一学习器更优越的泛化性能。集成学习的一般步骤为&#xff1a;1.生产一组“个体学习…...

记录一次root过程

设备: Redmi k40s 第一步&#xff0c; 解锁BL&#xff08;会重置手机系统&#xff01;&#xff01;&#xff01;所有数据都会没有&#xff01;&#xff01;&#xff01;&#xff09; 由于更新了澎湃OS系统, 解锁BL很麻烦, 需要社区5级以上还要答题。 但是&#xff0c;这个手机…...

函数(上)(C语言)

函数(上&#xff09; 一. 函数的概念二. 函数的使用1. 库函数和自定义函数(1) 库函数(2) 自定义函数的形式 2. 形参和实参3. return语句4. 数组做函数参数 一. 函数的概念 数学中我们其实就见过函数的概念&#xff0c;比如&#xff1a;一次函数ykxb&#xff0c;k和b都是常数&a…...

ARM-V9 RME(Realm Management Extension)系统架构之系统安全能力的侧信道抵御

安全之安全(security)博客目录导读 目录 一、系统PMU计数器 二、使用信号和功耗操作进行的故障攻击 一、系统PMU计数器 性能监测单元 (PMU) 计数器可能成为泄露机密信息的侧信道,如访问模式或受RME安全保障保护的安全状态下的执行控制流。以下规则补充了《Arm CoreSight™…...

Java高级技术探索:深入理解JVM内存分区与GC机制

文章目录 引言JVM内存分区概览垃圾回收机制&#xff08;GC&#xff09;GC算法基础常见垃圾回收器ParNew /Serial old 收集器运行示意图 优化实践结语 引言 Java作为一门广泛应用于企业级开发的编程语言&#xff0c;其背后的Java虚拟机&#xff08;JVM&#xff09;扮演着至关重…...

新视野大学英语2 词组 6.15

do you feel as confused and manipulated as i do with this question 你是否和我一样&#xff0c;对这个问题感到困惑和被操控 manipulated&#xff1a;被操控 defy common sense and contradict each other 违背常识且相互矛盾 defy&#xff1a;违背 contradict&#xf…...

【JavaScript】MDN

一、初识 1.1 基础 1.1.1 语言速成课 1.1.1.1 变量 ​ 变量是存储值的容器。首先用let关键字声明一个变量&#xff0c;后面跟着你给变量的名字 ​ 变量命名区分大小写 ​ 分号在JavaScript中是用来分隔语句的&#xff0c;但是如果语句后面有一个换行符(或者在{block}中只…...

Qt/C++中的异步编程

Qt/C++中的异步编程 1 介绍2 含义2.1 QtConcurrent2.2 std::future2.3 Qml中的Promise3 使用场景4 代码示例5 注意事项5.1异常处理5.2 线程安全5.3 性能优化5.4 线程间通信5.5 避免死锁1 介绍 异步编程是现代应用程序开发中不可或缺的一部分。它允许程序在执行耗时任务时保持响…...

解决javadoc一直找不到路径的问题

解决javadoc一直找不到路径的问题 出现以上问题就是我们在下载jdk的时候一些运行程序安装在C:\Program Files\Common Files\Oracle\Java\javapath下&#xff1a; 一开始是没有javadoc.exe文件的&#xff0c;我们只需要从jdk的bin目录下找到复制到这个里面&#xff0c;就可以使用…...

存储器的性能指标以及层次化存储器

存储器的性能指标 存储器有三个性能指标&#xff1a;速度、容量和位价&#xff08;每位价格&#xff09; 1.存储速度 &#xff08;1&#xff09;存取时间 想衡量存储速度&#xff0c;最直观的指标就是完成一次存储器读写操作所需要的时间&#xff0c;这叫做存取时间&#x…...

【C++】C++入门的杂碎知识点

思维导图大纲&#xff1a; namespac命名空间 什么是namespace命名空间namespace命名空间有什么用 什么是命名空间 namespace命名空间是一种域&#xff0c;它可以将内部的成员隔绝起来。举个例子&#xff0c;我们都知道有全局变量和局部变量&#xff0c;全局变量存在于全局域…...

致开发者:别再重复造轮子,这个开源商城系统让你把时间花在刀刃上

作为开发者&#xff0c;你是否厌倦了每次新项目都要从零搭建电商后台&#xff1f;商品、订单、会员、营销……这些基础模块耗费了你多少宝贵的创造力&#xff1f;今天&#xff0c;我们想和你聊聊一个能让你“拿来即用&#xff0c;改也不难”的解决方案——CRMEB开源商城系统。它…...

云容笔谈·东方红颜影像生成系统与ComfyUI工作流集成:可视化节点式创作

云容笔谈东方红颜影像生成系统与ComfyUI工作流集成&#xff1a;可视化节点式创作 如果你是一位数字艺术家或者技术美术&#xff0c;可能常常面临这样的困境&#xff1a;你有一个绝佳的创意&#xff0c;比如想生成一幅融合了东方古典美学与现代光影的“红颜”肖像&#xff0c;但…...

PyTorch 2.8镜像多场景落地:智慧农业病虫害识别模型田间部署方案

PyTorch 2.8镜像多场景落地&#xff1a;智慧农业病虫害识别模型田间部署方案 1. 田间AI的迫切需求 现代农业正面临病虫害防治的严峻挑战。传统人工巡查方式效率低下&#xff0c;一个熟练的技术员每天最多能检查3-5亩作物&#xff0c;而大型农场往往需要数十人同时作业。更棘手…...

【英飞凌】TC3XX单片机型号解码:从命名规则看芯片选型

1. 英飞凌TC3XX单片机命名规则解析 第一次接触英飞凌TC3XX系列单片机时&#xff0c;我完全被那一长串型号搞懵了。TC387TP、TC377T、TC397QP...这些看似随机的字母数字组合&#xff0c;其实隐藏着丰富的芯片信息。经过几个项目的实战&#xff0c;我终于摸清了这套命名规则的规律…...

Gepetto核心工具详解:函数反编译、变量重命名与代码注释

Gepetto核心工具详解&#xff1a;函数反编译、变量重命名与代码注释 【免费下载链接】Gepetto IDA plugin which queries OpenAIs gpt-3.5-turbo language model to speed up reverse-engineering 项目地址: https://gitcode.com/gh_mirrors/ge/Gepetto Gepetto是一款集…...

OpenClaw技能开发入门:为百川2-13B量化模型定制自动化模块

OpenClaw技能开发入门&#xff1a;为百川2-13B量化模型定制自动化模块 1. 为什么选择OpenClaw开发技能&#xff1f; 去年冬天&#xff0c;我为了给团队搭建一个内部天气查询助手&#xff0c;尝试过至少三种不同的自动化方案。要么是API调用太复杂&#xff0c;要么是自然语言处…...

BlueROV2进阶:巧用ArduSub参数配置实现多舵机协同控制

1. 从单舵机到多舵机协同的跨越 第一次用Pixhawk控制单个舵机转动时的兴奋感还记忆犹新&#xff0c;但当真正开始构建BlueROV2这样的水下机器人时&#xff0c;你会发现单一舵机控制远远不够。想象一下这样的场景&#xff1a;机械爪需要精准开合&#xff0c;云台要平稳转动&…...

网安学习路线!最详细没有之一!看了这么多分享网安学习路线的一个详细的都没有!

零基础小白&#xff0c;到就业&#xff01;入门到入土的网安学习路线&#xff01; 在各大平台搜的网安学习路线都太粗略了。。。。看不下去了&#xff01; 我把自己报班的系统学习路线&#xff0c;整理拿出来跟大家分享了&#xff01;点击下图&#xff0c;福利&#xff01; …...

Web开发中前端与Node服务中的信息安全与解决办法

Web开发中前端与Node服务中的信息安全与解决办法 input限制特殊字符和长度 漏洞描述&#xff1a; 永远不要相信用户输入的信息&#xff0c;如常规的注入脚本通过input输入之后被页面执行 整改办法 方法1&#xff1a;对于vue项目中ElementUI的el-input 和 原生input <el-in…...

36 Python 时序和文本:中文文本处理入门:为什么要先做分词和停用词过滤?

中文文本处理入门&#xff1a;为什么要先做分词和停用词过滤&#xff1f; 刚接触文本分析时&#xff0c;很多人都会有一个疑问&#xff1a; 文本明明已经有内容了&#xff0c;为什么不能直接拿去做分类、聚类或者情感分析&#xff1f; 这个问题其实正好指向了文本挖掘里最基础、…...