Qt自定义日志输出

Qt自定义日志输出

简略版:

c++ 复制代码
#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();
}

效果图:

详细版:

c++ 复制代码
#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中添加以下设置用于控制日志是否输出,如果不禁止注释掉即可

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

使用:

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

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

  • Logger.h
cpp 复制代码
#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
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
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修改即可

相关推荐
一叶之秋14124 小时前
QT背景介绍与环境搭建
开发语言·qt
QT 小鲜肉5 小时前
【QT/C++】Qt网络编程进阶:UDP通信和HTTP请求的基本原理和实际应用(超详细)
c语言·网络·c++·笔记·qt·http·udp
四维碎片9 小时前
【Qt】大数据量表格刷新优化--只刷新可见区域
开发语言·qt
一叶之秋141210 小时前
Qt开发初识
开发语言·qt
梵尔纳多12 小时前
ffmpeg 使用滤镜实现播放倍速
c++·qt·ffmpeg
QT 小鲜肉15 小时前
【QT/C++】Qt网络编程进阶:TCP网络编程的基本原理和实际应用(超详细)
c语言·开发语言·网络·c++·qt·学习·tcp/ip
Tony小周1 天前
使用QKeyEvent keyPress(QEvent::KeyPress, key模拟键盘发送事件,会导致主程序卡死
嵌入式硬件·qt
Larry_Yanan1 天前
QML学习笔记(五十)QML与C++交互:QML中单例C++对象
开发语言·c++·笔记·qt·学习·ui·交互
zhmhbest1 天前
Qt 全球峰会 2025:中国站速递 —— 技术中立,拥抱更大生态
开发语言·qt·系统架构
feiyangqingyun1 天前
Qt实时绘制飞行轨迹/移动轨迹实时显示/带旋转角度/平滑移动/效果一级棒/地面站软件开发/无人机管理平台
qt·无人机·集群地面站