版权声明:未经许可,请勿转载! https://blog.csdn.net/weixin_37204973/article/details/82530713
程序员每天必做的事情就是写 bug,那么调试信息就是必不可少的,网上博文大多是讲如何将调试信息保存至本地,但有时候我想记录到本地,并打印至ui 界面,或者其它地方,网上却没有很好的博文去介绍这个怎么做,所以只能想办法了,自己做了。
首先是调试消息处理的类
//MyDebug.cpp
#include "MyDebug.h"
#include <QMutex>
#include <iostream>
#include <QDateTime>
#include <QCoreApplication>
#include <QFile>
#include <QDir>
#include <QTextStream>
//接收调试信息的函数
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
static QMutex mutex;
QMutexLocker lock(&mutex);
QString text;
switch(type)
{
//如果是debug信息,那么直接打印至应用程序输出,然后退出本函数
case QtDebugMsg:
std::cout << msg.toStdString() << std::endl;
return ;
//如果是警告,或者是以下消息,则继续执行后面的数据处理
case QtWarningMsg:
text = QString("Warning...............................");
break;
case QtCriticalMsg:
text = QString("Critical..............................");
break;
case QtFatalMsg:
text = QString("Fatal.................................");
break;
default:
text = QString("Default...............................");
break;
}
//获取单例
MyDebug *instance = MyDebug::Instance();
//消息输出位置
QString context_info = QString("File: %1\r\nFunc: %2\r\nLine: %3")
.arg(QString(context.file))
.arg(QString(context.function))
.arg(context.line);
//消息打印时间
QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");
QString current_date = QString("Time: %1")
.arg(current_date_time);
//调试信息
QString message = QString("%1\r\n%2\r\n%3\r\n%4")
.arg(text)
.arg(current_date)
.arg(context_info)
.arg("MSG : "+msg);
//log 位置
QString logPahtHtml = "<a href = \"%1\">Click here to open the log directory.</a>\r\n";
logPahtHtml = logPahtHtml.arg(QCoreApplication::applicationDirPath()+"/"+instance->logPath());
//将调试信息格式化成 html 格式,
QString msgHtml = msg;
msgHtml.replace(" ", " ");
msgHtml.remove("\r");
msgHtml.replace("\n", "<br>");
msgHtml = QString("<font color=red>" + msgHtml + "</font>");
QString contextInfoHtml = context_info;
contextInfoHtml.remove("\r");
contextInfoHtml.replace("\n", "<br>");
//格式化后的调试信息
QString messageHtml = QString("%1<br>%2<br>%3<br>%4<br>%5")
.arg(text)
.arg(logPahtHtml)
.arg(current_date)
.arg(contextInfoHtml)
.arg("MSG : "+msgHtml);
//将调试信息写入文件
QFile file(instance->logPath() + instance->logName());
file.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream text_stream(&file);
text_stream << message << "\r\n\r\n\r\n";
file.flush();
file.close();
//将处理好的调试信息发送出去
instance->sigDebugStrData(message);
//将处理成 html 的调试信息发送出去
instance->sigDebugHtmlData(messageHtml);
//检查文件是否达到了指定大小
if(file.size() < 1024*1024) {
return ;
}
//log达到了限制值则将名字更改,防止文件越来越大
for(int loop = 1; loop < 100; ++loop) {
QString fileName = QString("%1/log_%2.txt").arg(instance->logPath()).arg(loop);
QFile file_1(fileName);
if(file_1.size() < 4) {
file.rename(fileName);
return ;
}
}
}
//MyDebug单例
MyDebug* MyDebug::self = nullptr;
MyDebug* MyDebug::Instance()
{
if(!self) {
QMutex muter;
QMutexLocker clocker(&muter);
if(!self) {
self = new MyDebug();
}
}
return self;
}
//安装消息器
void MyDebug::installMessageHandler()
{
qInstallMessageHandler(outputMessage);
}
//卸载消息器
void MyDebug::uninstallMessageHandler()
{
qInstallMessageHandler(0);
}
//建立文件路径
QString MyDebug::logPath()
{
QString current_date_file_name = QDateTime::currentDateTime().toString("yyyy-MM-dd");
QDir dir(QString("log/%1").arg(current_date_file_name));
if(!dir.exists()) {
dir.mkpath("./");
}
return dir.path() + "/" ;
}
QString MyDebug::logName()
{
return "log.txt";
}
MyDebug::MyDebug(QObject *parent) : QObject(parent)
{
static MyDebug::GC gc;
}
MyDebug::~MyDebug()
{
std::cout << "~MyDebug" << std::endl;
}
//垃圾自动回收
MyDebug::GC::~GC()
{
if (self != nullptr) {
delete self;
self = nullptr;
}
}
类做完了,使用前需要先安装消息器
//main.cpp
#include "mainwindow.h"
#include <QApplication>
#include "MyDebug.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//安装消息器
MyDebug::Instance()->installMessageHandler();
MainWindow w;
w.show();
return a.exec();
}
如果需要打印调试信息至ui ,那么使用下面这两个信号即可,可以说是很方便了
void sigDebugStrData(const QString &);
void sigDebugHtmlData(const QString &);
例
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include "MyDebug.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//绑定信号,将调试信息输出值ui
connect(MyDebug::Instance(), &MyDebug::sigDebugHtmlData, ui->textBrowser, &QTextBrowser::append);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
qDebug() << "这条消息只会打印至\"应用程序输出\"" <<endl;
qWarning()<< "这条消息会记录至文件,并打印至ui"<<endl;
}
下图就是程序运行效果,点击绿色字体,就会将 log 所在位置的文件夹打开
好啦,小弟拙作,如果不对的地方,欢迎大神们批评指正!