三十七、QT之日志输出

偶尔善良 提交于 2020-02-28 03:15:46

1.创建自定义消息处理器,并注册到系统

在项目的 main.cpp 中设置日志输出

#include "widget.h"
#include <QApplication>

#include <QMutex>
#include <QFile>
#include <QDateTime>
#include <QTextStream>

//消息处理器
QtMessageHandler defaultHandler = NULL;

void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    
    QString text;
    switch(type)
    {
    case QtDebugMsg:
        text = QString("Debug:");
        break;
    case QtInfoMsg:
        text = QString("Info:");
        break;
    case QtWarningMsg:
        text = QString("Warning:");
        break;
    case QtCriticalMsg:
        text = QString("Critical:");
        break;
    case QtFatalMsg:
        text = QString("Fatal:");
    }
    QString context_info = QString("File:(%1) Line:(%2) Function:%3")
            .arg(QString(context.file))
            .arg(context.line)
            .arg(context.function);
    QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");
    QString current_date = QString("(%1)").arg(current_date_time);
    QString message = QString("%1 %2 %3 %4").arg(text).arg(context_info).arg(msg).arg(current_date);
    
    //加锁
    static QMutex mutex;
    mutex.lock();
    
    //输出信息至文件中(读写、追加形式)
    QFile file("log.txt");
    file.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream text_stream(&file);
    text_stream << message << "\r\n";
    file.flush();
    file.close();
    
    //解锁
    mutex.unlock();
    
    //用系统原来的函数完成原来的功能. 比如输出到调试窗
    if (defaultHandler)
        defaultHandler(type, context, msg);
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    /**
     *     使用 qInstallMessageHandler() 注册一个自定义的消息处理器替换掉默认的 QtMessageHandler
     *     注意,QtMessageHandler不是一个类,看他的声明:
     * typedef void (*QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &);
     * 可以看到,QtMessageHandler 并不是一个类,而是一个函数指针,函数原型满足
     * (QtMsgType, const QMessageLogContext &, const QString &) 的函数都可以作为
     * QtMessageHandler 参数传递个 qInstallMessageHandler 函数中
     */
    //qInstallMessageHandler():想系统注册自定义消息处理器,并返回原来的消息处理器
    defaultHandler = qInstallMessageHandler(outputMessage);

    Widget w;
    w.show();

    return a.exec();
}

在 Rlease 模式下,会自动屏蔽文件名和行数,需要在 .pro 配置文件中添加;

#为了使日志在 Release 模式下也可输出文件名和代码行数
DEFINES += QT_MESSAGELOGCONTEXT

重新编译即可

2.使用

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    qDebug() << "界面开始初始化";
    ui->setupUi(this);
    qDebug() << "界面初始化完毕";
}

编译运行,则控制台输出如下:
在这里插入图片描述
编译后的应用目录出现 log.txt,如下:
在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!