Qt日志重定向
程序日志对于输出程序运行信息有着非常重要的作用,它可以帮助程序员定位问题所在,输出程序运转状态等
在使用QtCreator编写程序时,我们可以使用qDebug方便的将自己需要的信息输出,但是如果想将其显示到程序的控件上,又该怎样做呢?
经过一番搜索,我找到了将qDebug重定向的方法,可以将其输出的信息自由的存放到ui控件或文件中(搜到的大部分教程都是将日志信息重定向到文件中,容易让人误以为它只能重定向到文件)
qInstallMessageHandler
由于本人开发环境为Qt5,因此本文只介绍Qt5日志重定向方法qInstallMessageHandler(如果需要了解Qt4的日志重定向请搜索qInstallMsgHandler)
日志级别
Qt的调试信息分为五个级别:qDebug、qWarning、qInfo、qCritical、qFatal
- Debug:级别最低,可以随意输出的调试信息
- Info:用于反馈系统运行状态
- Warning:警告信息,可以修复的,不影响程序运行
- Critical:严重错误,可能导致程序无法正常运行
- Fatal:致命错误,程序无法正常运行
实现原理
qInstallMsgHandler是一个回调函数,由qDebug、qWarning、qCritical、qFatal函数出发,它们处理的消息文本会被qInstallMsgHandler所指向的回调函数截获,因此可以自己处理输出的消息文本
具体代码如下:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextEdit>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
static void logOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
static void write(QString str);
private slots:
void on_lineEdit_textChanged(const QString &arg1);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
需要注意的是: 自定义函数需要用static修饰,否则会提示如下报错信息
error: cannot convert 'MainWindow::logOutput' from type 'void (MainWindow::)(QtMsgType, const QMessageLogContext&, const QString&)' to type 'QtMessageHandler {aka void (*)(QtMsgType, const QMessageLogContext&, const QString&)}'
qInstallMessageHandler(logOutput);
^
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDateTime>
#include <QDebug>
QString text; //用于存放日志信息
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
qInstallMessageHandler(logOutput);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
qDebug() << arg1;
ui->textEdit->setText(text);
}
void MainWindow::write(QString str)
{
text = str;
}
void MainWindow::logOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QString text;
text.append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") + " ");
switch(type)
{
case QtDebugMsg:
text.append("Debug:");
break;
case QtWarningMsg:
text.append("Warning:");
break;
case QtCriticalMsg:
text.append("Critical:");
break;
case QtFatalMsg:
text.append("Fatal:");
}
text.append(msg);
write(text);
}
注意事项:
- 回调函数logOutput使用static修饰符进行修饰,因此其调用的write函数也必须为static函数
- 静态函数无法访问类的非静态成员,因此需要使用全局变量text来存放日志信息
程序运行效果:
如果需要直接在回调函数中操作控件内容,可以将使用代码生成控件,但必须将其设置为static类型
//例如:声明一个static修饰的QTextEdit对象
static QTextEdit *textEdit;
//然后直接在logOutput中处理全局字符文本text即可
textEdit->append(text);