Qt QDebug格式输出、自定义类输出及重定向输出Log

1、qDebug() 格式化输出

qDebug格式化支持printf的格式化标识符

如果向函数传递格式字符串和参数列表,它的工作方式类似于C printf()函数。 格式应该是Latin-1字符串。

格式化demo

代码如下(示例):

void Widget::Printf() {
    QString str = "qwe";
    QDateTime dt = QDateTime::fromTime_t(time(NULL));
    qreal pi = 3.141592653589793;
    QString str_pi = QString::number(pi, 'g', 16);

    // 格式化输出
    qDebug("this is %s, Today is %04d-%02d-%02d, PI = %s", str.toLocal8Bit().data(), dt.date().year(),
           dt.date().month(), dt.date().day(), str_pi.toLocal8Bit().data());
}

2、qDebug() 自定义类输出

2.1、重载操作符 << 放在与类声明的头文件中, 在类的声明外部

mycalss类的头文件

代码如下(示例):

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QDebug>
#include <QString>

class MyClass {
public:
    MyClass();

    int Get_Id() const {return _id;}
    QString Get_Name() const {return _name;}

private:
    int _id = 1;
    QString _name = "qwe";
};

QDebug operator<<(QDebug debug, const MyClass &my_class);

#endif // MYCLASS_H

mycalss类的源文件

代码如下(示例):

#include "myclass.h"

MyClass::MyClass() {

}


QDebug operator<<(QDebug debug, const MyClass &my_class) {
    debug << "Id =" << my_class.Get_Id() << "name =" << my_class.Get_Name();
    return debug;
}

2.2、重载操作符 << 友元函数声明

mycalss类的头文件

代码如下(示例):

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QDebug>
#include <QString>

class MyClass {
protected:
    friend QDebug operator<<(QDebug debug, const MyClass &my_class);
    
public:
    MyClass();

    int Get_Id() const {return _id;}
    QString Get_Name() const {return _name;}

private:
    int _id = 1;
    QString _name = "qwe";
};
#endif // MYCLASS_H

mycalss类的源文件

代码如下(示例):

#include "myclass.h"

MyClass::MyClass() {

}
QDebug operator<<(QDebug debug, const MyClass &my_class) {
    debug << "Id =" << my_class._id << "name =" << my_class._name;
    return debug;
}

2.3、调用

void Widget::Printf_Class() { // 自定义类输出到qDebug
    MyClass my_class;

    qDebug() << my_class;
}

3、qDebug() 输出重定向 LOG 文件

多线程输出是需要考虑线程安全问题

QMutex 互斥量:QMutex类提供的是线程之间的访问顺序化。QMutex的目的是保护一个对象、数据结构或者代码段,所以同一时间只有一个线程可以访问它。

QMutexLocker 类:使用该类不用手动加锁释放锁,定义自动加锁,出作用于自动解锁。(RAII 资源获取即初始化)

定义相关的变量和接口

关键代码如下(示例):

QMutex mutex; // 为了支持多线程,需要使用锁来保护对日志文件的操作
QtMessageHandler system_default_message_handler = NULL; // 用来保存系统默认的输出接口
// 替换接口
void Custom_Message_Handler(QtMsgType type, const QMessageLogContext& context, const QString& info) {
    // 信息格式化
    QString log = QString::fromLocal8Bit("msg-[%1], file-[%2], func-[%3], category-[%4]\n")
            .arg(info).arg(context.file).arg(context.function).arg(context.category);
    bool bok = true;

    switch (type) {
    case QtDebugMsg:
        log.prepend("Qt dbg:");
        break;
    case QtWarningMsg:
        log.prepend("Qt warn:");
        break;
    case QtCriticalMsg:
        log.prepend("Qt critical:");
        break;
    case QtFatalMsg:
        log.prepend("Qt fatal:");
        break;
    case QtInfoMsg:
        log.prepend("Qt info:");
        break;
    default:
        bok = false;
        break;
    }
    if(bok) {
        // 加锁
        QMutexLocker locker(&mutex);

        QString str_file_name = "./log/log.inf";
        QString str_dir = "./log";
        QDir dir;
        dir.mkpath(str_dir);

        QFile file(str_file_name);

        if(! file.open(QFile::ReadWrite | QFile::Append)) {
            return;
        }

        file.write(log.toLocal8Bit().data());
        file.close();
    }

    if(bok) {
        // 调用系统原来的函数完成信息输出, 调试窗口
        if(NULL != system_default_message_handler) {
            system_default_message_handler(type, context, log);
        }
    }
}

在主函数进行输出重定向绑定

// 输出重定向
    system_default_message_handler = qInstallMessageHandler(Custom_Message_Handler);

运行结果图

 本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值