当前位置: 首页 > article >正文

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

因为在嵌入式中调试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 退出按钮均可退出


http://www.kler.cn/a/161778.html

相关文章:

  • ADO.NET数据处理框架
  • 面经—科大讯飞
  • 分组校验在Spring中的应用详解
  • 网络安全---安全见闻
  • PMP--知识集锦囊
  • Elmo驱动器上位机软件的详细配置
  • 区分node,npm,nvm
  • uni-app实现安卓原生态调用身份证阅读器读卡库读身份证和社保卡、银行卡、IC卡等功能
  • 匹配不包含同时出现两次 “ago“ 的行
  • Redis server启动源码
  • vue 商品列表案例
  • JavaSE基础50题:11. 输出一个整数的每一位
  • CentOS 7.9 安装 k8s(详细教程)
  • Vue.js实现可编辑表格并高亮修改的单元格
  • 基于remix+metamask+ganache的智能合约部署调用
  • 注解 @Autowired 和 @Resource
  • OpenGL ES 帧缓冲对象介绍和使用示例
  • AI烟火识别智能视频分析系统解决方案
  • Dockerfile详解#如何编写自己的Dockerfile
  • Matlab 用矩阵画图
  • JAVA 多线程并发(一)
  • Jmeter接口测试
  • STL(一)(pair篇)
  • 【Docker二】docker网络模式、网络通信、数据管理
  • Oracle11g RAC无法使用VIP或SCAN IP连接数据库的解决方案
  • 人工智能_机器学习061_KKT条件公式理解_原理深度解析_松弛变量_不等式约束---人工智能工作笔记0101