QT实现类似qDebug()打印输出之mDebug()

需求简介:由于做的是嵌入式工业相机,我们的软件运行在linux上,每次测试软件时,需要查看测试数据时只能写日志或者通过串口打印到PC。当在现场使用时没有电脑想看程序时时运行的数据就做不到,唯一的办法就是写日志,然后把日志拷贝出来拿到电脑上查看,这样一来非常浪费时间,也不能在设备上看时时的测试数据。基于此自己写了这个类似与qDebug()打印信息的工具mDebug(),把数据打印到自己指定的窗口,这样就解决了问题,提高了现场的测试效率,程序运行界面如下所示:

这个界面做的很类似ubuntu的终端界面。mDebug()的实现原理主要是使用了C++的重载功能,对不同的数据类型都重载了<<运算符,使mDebug()可以打印指定的数据类型,为了方便使用mDebug()能打印的数据类型几乎包含了QT的所有基本数据类和opencv的所有基本数据类型。之所以也要支持打印opencv的数据类,是因为我们工业相机是基于opencv这个开源库实现的。下面介绍mDebug()的实现。

创建一个MyDebug类(MyDebug.h 和 MyDebug.cpp)

第一:MyDebug.h文件内容介如下。

//引入opencv库
#include <unistd.h>
#include <cv.h>

//引入QT类
#include <QTextEdit>
#include <QDateTime>
#include <QFile>

using namespace cv;
using namespace std;

//宏 返回MyDebug对象
#define mDebug() MyDebug::myDebug()

//做类前置声明
class QPoint;
class QPointF;
class QRect;
class QRectF;
class CvPoint;
class CvPoint2D32f;
class MyDebugDlg;
class QTextEdit;

1.1、在MyDebug类中对想要打印的数据类型进行 <<运算符重载,所有要重载的数据类型如下。

 //重载 << 运算符
    MyDebug& operator<<(const QString &sMsg);              //重载 << 运算符 打印QString
    MyDebug& operator<<(const String &sMsg);               //重载 << 运算符 打印String
    MyDebug& operator<<(const bool &sMsg);                 //重载 << 运算符 打印bool
    MyDebug& operator<<(const char &sMsg);                 //重载 << 运算符 打印char
    MyDebug& operator<<(const signed short &sMsg);        //重载 << 运算符 打印short
    MyDebug& operator<<(const unsigned short &sMsg);      //重载 << 运算符 打印unsigned short
    MyDebug& operator<<(const signed int &sMsg);          //重载 << 运算符 打印int
    MyDebug& operator<<(const unsigned int &sMsg);        //重载 << 运算符 打印unsigned int
    MyDebug& operator<<(const signed long &sMsg);         //重载 << 运算符 打印long
    MyDebug& operator<<(const unsigned long &sMsg);       //重载 << 运算符 打印undigned long
    MyDebug& operator<<(const qint64 &sMsg);              //重载 << 运算符 打印qint64
    MyDebug& operator<<(const quint64 &sMsg);             //重载 << 运算符 打印quint64
    MyDebug& operator<<(const float &sMsg);               //重载 << 运算符 打印float
    MyDebug& operator<<(const double &sMsg);              //重载 << 运算符 打印double
    MyDebug& operator<<(const char* sMsg);                //重载 << 运算符 打印char*
    MyDebug& operator<<(const QByteArray &sMsg);          //重载 << 运算符 打印QByteArray
    MyDebug& operator<<(const QPoint &sMsg);              //重载 << 运算符 打印QPoint
    MyDebug& operator<<(const QPointF &sMsg);             //重载 << 运算符 打印QPointF
    MyDebug& operator<<(const QRect &sMsg);               //重载 << 运算符 打印QRectF
    MyDebug& operator<<(const QRectF &sMsg);              //重载 << 运算符 打印CvPoint
    MyDebug& operator<<(const CvPoint &sMsg);             //重载 << 运算符 CvPoint
    MyDebug& operator<<(const CvPoint2D32f &sMsg);        //重载 << 运算符 打印CvPoint2D32f
    MyDebug& operator<<(const Point &sMsg);               //重载 << 运算符 打印CvPoint2D32f
    MyDebug& operator<<(const void *sMsg);                //重载 << 运算符 打印指针地址

从重载的形式上看,每种数据类打印完之后,该函数都会引用返回MyDebug对象,这是为了可以使用<<运算符可以连续打印信息到串口。如果不引用返回MyDebug对象,一次一行就只能打印一个信息,而不能在一行打印多个不同的数据类型,所以引用返回这是必须的。

1.2、在MyDebug类里面添加三个静态函数,分别返回MyDebug对象的函数、打印信息到指定窗口的函数、写信息到日志文件的函数,三个函数原形如下所示:

public:

  //返回MyDebug对象
    static MyDebug myDebug(){return MyDebug();}

    //设置信息显示到哪个窗口
    static void setWrite2Wnd(QTextEdit *pEdit) {m_pEdit = pEdit;}

    //设置是否把信息写到日志文件
    static void setWrite2Log(bool bWrite2Log)  {m_bWrite2Log = bWrite2Log;}

以上三个函数是public类型的,是提供给外部使用的使用。在MyDebug类添加两个私有静态成员变量,一个是控制是否把打印信息写到日志文件,一个是显示信息的窗口指针。两个成员变量声明如下:

private:
    static bool m_bWrite2Log;               //是否写到日志文件中 true:写 false:不写
    static QTextEdit *m_pEdit;              //显示信息的控件指针

1.3、声明了静态成员,就必须对静态成员初始化,C++的语言,以下是初始化原形。

bool MyDebug::m_bWrite2Log = false;
QTextEdit* MyDebug::m_pEdit = NULL;

1.4、另外在声明6个私有函数,函数的声明即作用如下:

private:
    void initWnd(); //初始化打印信息串口,清空旧内容、设置格式
    void initLog(); //初始化日志文件,创建日志文件

    QString stringToHtmlFilter(QString str);//格式化字符串,比如想设置信息的颜色大小,可以同个这个函数格式字符格式
    void Write(const QString &sMsg);        //在每个重载<<运算符的地方调用,把打印信息显示到窗口和写到日志
    void write2Log(const QString &sMsg);    //将Debug信息保存到 log.txt
    void write2Wnd(const QString &sMsg);    //将Debug信息显示到 m_pEdit

以上6个函数是私有类型,只给MyDebug类使用,不对外提供使用权限。

第二:MyDebug.cpp文件内容介如下。

2.1、实现构造函数

MyDebug::MyDebug()
{
    initWnd();//初始化打印信息串口,清空旧内容、设置格式
    initLog();//初始化日志文件,创建日志文件
}

2.2、实现重载<<函数

//实现打印QString数据类型
MyDebug& MyDebug::operator<<(const QString &sMsg)
{
    Write(sMsg);
    return *this;//返回MyDebug对象,这是重点
}

//实现打印String数据类型
MyDebug& MyDebug::operator<<(const String &sMsg)
{
    QString s(sMsg.c_str());
    Write(s);
    return *this;//返回MyDebug对象,这是重点
}

//实现打印bool数据类型
MyDebug& MyDebug::operator<<(const bool &sMsg)
{
    QString s = sMsg ? QString("true") : QString("false");
    Write(s);
    return *this;//返回MyDebug对象,这是重点
}

....太多了就不一一列举了,大家可以参考以上三个例子来写。

其它的函数实现就不一一写了,待会会把工程源码上传,需要的可以下载。

第三:MyDebug的使用。

3.1、在需要打印的地方引入MyDebug.h

#include "MyDebug.h"

3.2、使用例子如下:

例1:打印字符串

 MyDebug::setWrite2Wnd(ui->textEdit); //设置打印窗口对象指针
    MyDebug::setWrite2Log(true);         //设置打印信息保存到日志文件

    //打印二行信息到窗口并保存到日志文件
    mDebug() << tr("this is MyDebug program");
    mDebug() << tr("create time is 2018.09.20");

例2:打印整数、浮点数、双精度浮点数、bool

mDebug() << 18 << 26 << 31.2 << 44.9 << true ;

例3:打印QT和opencv结构体数据类型。

mDebug() << Point(10, 10) << QPoint(100, 100);

例4:打印指针类型

mDebug() << ui;

第四:测试结果

结果1:在窗口打印5行信息

结果2:日志文件

工程源码下载:https://download.csdn.net/download/cwj066/10680629

猜你喜欢

转载自blog.csdn.net/cwj066/article/details/82786996