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

yumo6664小时前技术文章3

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 文件

QT开发交流+赀料君羊:714620761

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

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开发经验小技巧181-185(qt开发程序)

没有最新的文章了...

相关文章

Qt多线程编程两种方式详解(qt开启线程的三种方式)

QT的多线程编程主要有两种方式:第一种是继承自QThread,然后重写run()函数;第二种是继承自QObject,然后把整个对象moveToThread;两种方法比较:第一种方法只有run()函数是...

Qt多线程创建(qt多线程直接处理数据)

【为什么要用多线程?】传统的图形用户界面应用程序都只有一个执行线程,并且一次只执行一个操作。如果用户从用户界面中调用一个比较耗时的操作,当该操作正在执行时,用户界面通常会冻结而不再响应。这个问题可以用...

正点原子I.MX6U嵌入式Qt开发指南:第十章《多线程》

今日头条/西瓜视频/抖音短视频 同名:正点原子原子哥今日头条/西瓜视频/抖音短视频账号:正点原子-原子哥感谢各位的关注和支持,你们的关注和支持是正点原子无限前进的动力。第十章《多线程》我们写的一个应用...

Qt 的4种多线程实现详解(qt实现多线程文件传输)

为何需要多线程?1、进行耗时操作时,可以处理用户的其他输入输出。比如,如果在UI线程里面进行耗时操作,界面会不响应用户操作。2、提升程序性能。现在的电脑一般都是多核CPU,多线程并行处理事务,可以大大...

Qt快速入门(工程的创建、UI界面布局、多线程、项目)

本文档将介绍QT工程的创建、UI界面布局,并以计数器为例了解QT中多线程的用法,最终完成一个基础的QT项目。1 创建QT工程文件在安装好QT之后,能够在其安装组件中找到Qt Creator,点击设置项...

Qt多线程1:QThread(Qt多线程通信)

1. Qt多线程概述Qt有两种多线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类转移到一个Thread里。 Qt4.8之前都是使用继承QThread的ru...