实现功能
1、将qDebug、qWarning等输出显示到一个窗口部件
2、窗口部件根据日志等级显示不同颜色
实现方法
日志重定向:qInstallMessageHandler
定义MsgHandlerWapper类,qDebug、qWarning 等的输出会通过该类的 message 信号发送出来
定义LogViewer类,采用QListWidget,显示日志信息,关联MsgHandlerWapper信号
日志传递到界面过程如下图所示:

最终效果

代码
MsgHandlerWapper.h
#ifndef MSGHANDLERWAPPER_H
#define MSGHANDLERWAPPER_H
#include <QObject>
class MsgHandlerWapper: public QObject
{
Q_OBJECT
public:
static MsgHandlerWapper *instance();
signals:
void message(QtMsgType type, const QString &msg);
private:
MsgHandlerWapper();
static MsgHandlerWapper *m_instance;
};
#endif // MSGHANDLERWAPPER_HMsgHandlerWapper.cpp
qMessageOutput重定向函数中,通过MsgHanderWapper发射message信号
#include "MsgHandlerWapper.h"
#include <QtCore/QMetaType>
#include <QtCore/QMutex>
#include <QtCore/QMutexLocker>
#include <QtCore/QCoreApplication>
void qMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QMetaObject::invokeMethod(MsgHandlerWapper::instance(), "message"
, Q_ARG(QtMsgType, type)
, Q_ARG(const QString, msg));
QByteArray localMsg = msg.toLocal8Bit();
switch (type)
{
case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u)\n", localMsg.constData(), context.file, context.line);
break;
case QtInfoMsg:
fprintf(stderr, "Info: %s (%s:%u)\n", localMsg.constData(), context.file, context.line);
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %s (%s:%u)\n", localMsg.constData(), context.file, context.line);
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %s (%s:%u)\n", localMsg.constData(), context.file, context.line);
break;
case QtFatalMsg:
fprintf(stderr, "Fatal: %s (%s:%u)\n", localMsg.constData(), context.file, context.line);
abort();
}
}
MsgHandlerWapper *MsgHandlerWapper::m_instance = 0;
MsgHandlerWapper *MsgHandlerWapper::instance()
{
static QMutex mutex;
if (!m_instance)
{
QMutexLocker locker(&mutex);
if (!m_instance)
{
m_instance = new MsgHandlerWapper;
}
}
return m_instance;
}
MsgHandlerWapper::MsgHandlerWapper()
: QObject(qApp)
{
qRegisterMetaType<QtMsgType>("QtMsgType");
qInstallMessageHandler(qMessageOutput);
}
LogViewer.h
#ifndef LOGVIEWER_H
#define LOGVIEWER_H
#include <QFrame>
namespace Ui
{
class LogViewer;
}
class LogViewer : public QFrame
{
Q_OBJECT
public:
enum MessageLevel
{
NORMAL_LEVEL = 0,
WARNING_LEVEL = 1,
ERROR_LEVEL = 2
};
explicit LogViewer(QWidget *parent = 0);
~LogViewer();
int maxLines() const;
void setMaxLines(int num);
void outputMessage(const MessageLevel &level, const QString &msg);
private slots:
void outputMessage(QtMsgType type, const QString &msg);
private:
Ui::LogViewer *ui;
int m_maxLines;
};
#endif // LOGVIEWER_HLogViewer.cpp
connect到MsgHandlerWapper实例的message信号
设置前景与背景改变颜色
#include "LogViewer.h"
#include "ui_LogViewer.h"
#include <QDateTime>
#include "MsgHandlerWapper.h"
LogViewer::LogViewer(QWidget *parent) :
QFrame(parent),
ui(new Ui::LogViewer), m_maxLines(100)
{
ui->setupUi(this);
connect(MsgHandlerWapper::instance(),
SIGNAL(message(QtMsgType, QString)),
SLOT(outputMessage(QtMsgType, QString)));
}
LogViewer::~LogViewer()
{
delete ui;
}
int LogViewer::maxLines() const
{
return m_maxLines;
}
void LogViewer::setMaxLines(int num)
{
m_maxLines = num;
}
void LogViewer::outputMessage(QtMsgType type, const QString &msg)
{
switch (type)
{
case QtDebugMsg:
outputMessage(NORMAL_LEVEL, msg);
break;
case QtInfoMsg:
outputMessage(NORMAL_LEVEL, msg);
break;
case QtWarningMsg:
outputMessage(WARNING_LEVEL, msg);
break;
case QtCriticalMsg:
outputMessage(ERROR_LEVEL, msg);
break;
case QtFatalMsg:
outputMessage(ERROR_LEVEL, msg);
}
}
void LogViewer::outputMessage(const LogViewer::MessageLevel &level, const QString &msg)
{
if(ui->listWidget->count() >= m_maxLines)
{
ui->listWidget->removeItemWidget(ui->listWidget->takeItem(0));
}
QDateTime current_date_time = QDateTime::currentDateTime();
QString current_date = current_date_time.toString("yyyy.MM.dd hh:mm:ss.zzz ddd");
QString text = tr("[%1] %2").arg(current_date).arg(msg);
QListWidgetItem *newItem = new QListWidgetItem(text);
newItem->setSizeHint(QSize(60, 30));
switch (level)
{
case MessageLevel::NORMAL_LEVEL:
{
}
break;
case MessageLevel::WARNING_LEVEL:
{
newItem->setBackground(QColor(255, 185, 15));
}
break;
case MessageLevel::ERROR_LEVEL:
{
newItem->setBackground(QColor(255, 0, 0));
newItem->setForeground(QColor(255, 255, 255));
}
break;
default:
break;
}
ui->listWidget->addItem(newItem);
ui->listWidget->scrollToBottom();
}
版权声明:本文为qq_40602000原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。