QT 重定向qdebug输出到自绘界面

2023-12-15 00:02:17

因为在嵌入式中调试qt需要查看输出信息,特意写了一个类用户便捷查看qdebug信息

界面如下:

提供了开始,停止,保存,清空,退出功能,具体代码下文给出

文件如下

#ifndef QDEBUGREDIRECT_H
#define QDEBUGREDIRECT_H
/*
 *qdebug  重定向类 定向到界面控件
 *李吉磊 2023.12.7
 *
*/

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QTextEdit>
#include <QWidget>
#include <QMutex>


class qDebugRedirect : public QObject
{
    Q_OBJECT
public:
    qDebugRedirect();
    void showWidget();    //展示界面
    void closeWidget();    //关闭界面
    static void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);

private:
    void InitWidget();
    void StartRedirect();     //启动注册
    void StopRedirect();      //停止注册
    void Save2File();         //将界面文本内容保存到本地
    QWidget * m_widget;  //界面
    QTextEdit * m_Edit;
    QMutex m_mutex;
};

#endif // QDEBUGREDIRECT_H
#include "qdebugredirect.h"
#include <QGridLayout>
#include <QDebug>
#include <QDateTime>
#include <QDir>
qDebugRedirect * g_qDebugRedirect;

qDebugRedirect::qDebugRedirect()
{
    m_widget = nullptr;
    g_qDebugRedirect = this;
    //下面两行为在构造该类时启动重定向,后续只要展示出界面即可查看信息
    InitWidget();
    StartRedirect();
}

void qDebugRedirect::myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    // 加锁
    g_qDebugRedirect->m_mutex.lock();

    //信息分类
    QString strMsg("");
    QByteArray localMsg = msg.toLocal8Bit();
    switch(type)
    {
    case QtDebugMsg:
        strMsg = QString("Debug:");
        break;
    case QtInfoMsg:
        strMsg = QString("Info:");
        break;
    case QtWarningMsg:
        strMsg = QString("Warning:");
        break;
    case QtCriticalMsg:
        strMsg = QString("Critical:");
        break;
    case QtFatalMsg:
        strMsg = QString("Fatal:");
        break;
    default:
        break;
    }

    //文件名、函数名、行数
    strMsg += QString("Function: %1  File: %2  Line: %3 ").arg(context.function).arg(context.file).arg(context.line);

    // 时间和内容
    QString strDateTime = QDateTime::currentDateTime().toString("hh:mm:ss");
    QString strMessage = QString("%1 %2:%3").arg(strDateTime).arg(strMsg).arg(localMsg.constData());
    int maxLen = 2*1024*1024;
    int len = g_qDebugRedirect->m_Edit->toPlainText().length();
    if(len > maxLen)
        g_qDebugRedirect->m_Edit->clear();
    g_qDebugRedirect->m_Edit->append(strMessage);
    g_qDebugRedirect->m_Edit->moveCursor(QTextCursor::End);

    // 解锁
    g_qDebugRedirect->m_mutex.unlock();

}


void qDebugRedirect::StartRedirect()
{
    qInstallMessageHandler(myMessageOutput);
}

void qDebugRedirect::StopRedirect()
{
    qInstallMessageHandler(nullptr);
}

void qDebugRedirect::InitWidget()
{
    if(m_widget == nullptr)
    {
        m_widget = new QWidget();
        QGridLayout * glay = new QGridLayout();
        glay->setSpacing(0);
        glay->setMargin(0);
        glay->setContentsMargins(0,0,0,0);
        m_widget->setLayout(glay);
        QPushButton * pbClose = new QPushButton();  //关闭界面按钮
        pbClose->setText("close");
        QObject::connect(pbClose,&QPushButton::clicked,this,[=](){
            closeWidget();
            //qDebug() << "close";
        });
        glay->addWidget(pbClose,0,8,1,1);
        QPushButton * pbBegin = new QPushButton();  //开始按钮
        pbBegin->setText("start");
        QObject::connect(pbBegin,&QPushButton::clicked,this,[=](){StartRedirect();});
        glay->addWidget(pbBegin,1,0,1,2);
        QPushButton * pbEnd = new QPushButton();    //结束按钮
        pbEnd->setText("stop");
        QObject::connect(pbEnd,&QPushButton::clicked,this,[=](){StopRedirect();});
        glay->addWidget(pbEnd,1,2,1,2);
        QPushButton * pSave = new QPushButton();    //保存按钮
        pSave->setText("save");
        QObject::connect(pSave,&QPushButton::clicked,this,[=](){Save2File();});
        glay->addWidget(pSave,1,4,1,2);
        QPushButton * pClear = new QPushButton();    //清理按钮
        pClear->setText("clear");
        QObject::connect(pClear,&QPushButton::clicked,this,[=](){
            m_Edit->clear();
        });
        glay->addWidget(pClear,1,8,1,1);


        //展示控件
        m_Edit = new QTextEdit();
        glay->addWidget(m_Edit,2,0,6,9);
        //m_widget->setWindowFlag(Qt::WindowStaysOnTopHint,true);
        //m_widget->setWindowFlags(Qt::FramelessWindowHint);
        //m_widget->setWindowModality(Qt::ApplicationModal);
        m_widget->resize(800,600);
    }
}

void qDebugRedirect::showWidget()    //展示界面
{
    InitWidget();
    m_widget->show();
}

void qDebugRedirect::closeWidget()    //关闭界面
{
    if(m_widget)
    {
        m_widget->close();
        delete m_widget;
        m_widget = nullptr;
    }
}

void qDebugRedirect::Save2File()
{
    //创建log文件夹
    qDebug() << "currentPath : " << QDir::currentPath();

    QDir dir("log");
    if (!dir.exists())
    {
        QDir dir;
        bool b = dir.mkdir("log");
        qDebug() << "dir.mkdir(\"log\") = "  << b;
    }

    //创建log文件
    QString currentDate = QDateTime::currentDateTime().toString("yyyyMMdd");
    QString logName = "log" + currentDate + ".txt";
    QString logFileName = "log/" + logName;

    //写入文件
    QFile file(logFileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Append))
    {
        qDebug() << "file.open : " << logFileName << "faild";
        file.close();
        return ;
    }
    qDebug() << "file.open : " << logFileName << "succeed";
    QTextStream stream(&file);
    stream << m_Edit->toPlainText() << "\r\n";;
    file.flush();
    file.close();
}



使用方法也很简单

先构造

qDebugRedirect * m_widget;

m_widget = new qDebugRedirect();

然后展示界面或关闭界面

m_widget->showWidget();? ?展示界面

m_widget->closeWidget();? 关闭界面

当然了界面自带close 按钮 或者 窗体的x 退出按钮均可退出

文章来源:https://blog.csdn.net/qq_37059136/article/details/134853231
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。