一:介绍
软件里面的打印信息,通过日志记录到文件或者输出到控件上,方便查看。
二:调试信息
Qt有Debug、Warning、Info、Critical、Fatal五种级别的调试信息。
- qDebug--------调试信息
- qWarning--------警告信息
- qInfo--------警告信息
- qCritical--------严重错误
- qFatal--------致命错误
三:调试消息重定向
Qt4提供了qInstallMsgHandler函数
Qt5提供了qInstallMessageHandler函数
对qDebug、qWarning、qCritical、qFatal等函数输出信息的重定向处理。
四:实现方法
函数注册回调函数:
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
函数里面实现log信息的输出。
五:例程1:输出到log文件
函数中通过qInstallMessageHandler注册回调函数
2.在myMessageOutput函数中把调试信息写入到文件中
#include ""
#include <QApplication>
#include <QMutex>
#include <QDateTime>
#include <QDebug>
#include <QDir>
QMutex mutex;
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
//创建log文件夹
QDir dir("log");
if (!dir.exists())
{
QDir dir;
dir.mkdir("log");
}
//创建log文件
QString currentDate = QDateTime::currentDateTime().toString("yyyyMMdd");
QString logName = "log" + currentDate + ".txt";
QString logFileName = "log/" + logName;
// 加锁
mutex.lock();
QByteArray localMsg = msg.toLocal8Bit();
//信息分类
QString strMsg("");
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;
}
//Release 版本默认不包含context这些信息:文件名、函数名、行数,需要在.pro项目文件加入以下代码,加入后最好重新构建项目使之生效:
//DEFINES += QT_MESSAGELOGCONTEXT
//在.pro文件定义以下的宏,可以屏蔽相应的日志输出
//DEFINES += QT_NO_WARNING_OUTPUT
//DEFINES += QT_NO_DEBUG_OUTPUT
//DEFINES += QT_NO_INFO_OUTPUT
//文件名、函数名、行数
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());
//写入文件
QFile file(logFileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Append))
{
file.close();
return ;
}
QTextStream stream(&file);
stream << strMessage << "\r\n";;
file.flush();
file.close();
// 解锁
mutex.unlock();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qInstallMessageHandler(myMessageOutput);
//测试
qDebug("This is a debug test message.");
return a.exec();
}
六:例程2:输出到UI控件上
函数中通过qInstallMessageHandler注册回调函数
2.在myMessageOutput函数中把调试信息通过appendMsgOut()发送到主窗口MainWindow
#include ""
#include <QApplication>
#include <QMutex>
#include <QDateTime>
#include <QDebug>
#include <QDir>
MainWindow *pw = nullptr;
QMutex mutex;
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
// 加锁
mutex.lock();
QByteArray localMsg = msg.toLocal8Bit();
//信息分类
QString strMsg("");
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;
}
// 设置输出信息格式
QString strDateTime = QDateTime::currentDateTime().toString("hh:mm:ss");
QString strMessage = QString("%1 %2:%3").arg(strDateTime).arg(strMsg).arg(localMsg.constData());
// 输出信息到UI
pw->appendMsgOut(strMessage);
// 解锁
mutex.unlock();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qInstallMessageHandler(myMessageOutput);
//主窗口
MainWindow w;
pw = &w;
w.show();
return a.exec();
}
3.在MainWindow中实现信息输出到控件上,注意多线程操作Ui时要用信号,不然容易卡死界面
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void appendMsgOut(QString msg);
signals:
void sglAppendText(QString);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include ""
#include "ui_mainwindow.h"
#include <QDebug>
#include <QDateTime>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//打印信息到textEdit控件上
ui->textEdit_msgOut->document()->setMaximumBlockCount(100);
connect(this,SIGNAL(sglAppendText(QString)),ui->textEdit_msgOut,SLOT(append(QString)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::appendMsgOut(QString msg)
{
if(msg.contains("Debug:")){
msg = "<font color=\"#000000\">" + msg + "</font> ";
}else if (msg.contains("Info:")) {
msg = "<font color=\"#0000FF\">" + msg + "</font> ";
}else if (msg.contains("Warning:")) {
msg = "<font color=\"#FF00FF\">" + msg + "</font> ";
}else if (msg.contains("Critical:")) {
msg = "<font color=\"#FF0000\">" + msg + "</font> ";
}else if (msg.contains("Fatal:")) {
msg = "<font color=\"#FF0000\">" + msg + "</font> ";
}else {
msg = "<font color=\"#000000\">" + msg + "</font> ";
}
//不同线程直接调用会导致程序崩溃,改用信号槽的方式
//ui->textEdit_msgOut->append(msg);
emit sglAppendText(msg);
}