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 退出按钮均可退出