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修改即可

相关推荐
狗蛋儿l3 小时前
qt 3d航迹图
开发语言·qt·3d
Ethon_王6 小时前
走进Qt--信号与槽机制详解与实战
c++·qt
十五年专注C++开发6 小时前
Qt中的全局函数讲解集合(全)
开发语言·c++·qt·算法
.hopeful.8 小时前
基于QT的仿QQ音乐播放器
开发语言·c++·qt
溟洵8 小时前
【C++ Qt】快速上手 显⽰类控件(Label、LCDNumber、ProcessBar、CalendarWidget)
开发语言·c++·qt
我真的不会C21 小时前
QT中的事件及其属性
开发语言·qt
Ethon_王21 小时前
走进Qt--工程文件解析与构建系统
c++·qt
zhangzhangkeji1 天前
QT6 源(45):分隔条 QSplitter 允许程序的用户修改布局,程序员使用 IDE时,就是分隔条的用户,以及其 QSplitter 源代码
qt
Ethon_王1 天前
Qt 入门&安装
qt
OpenC++1 天前
【C++QT】Layout 布局管理控件详解
c++·经验分享·qt·leetcode