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


MsgHandlerWapper.h
- #ifndef MSGHANDLERWAPPER_H
- #define MSGHANDLERWAPPER_H
-
- #include
-
-
- 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_H
MsgHandlerWapper.cpp
qMessageOutput重定向函数中,通过MsgHanderWapper发射message信号
- #include "MsgHandlerWapper.h"
- #include
- #include
- #include
- #include
-
- 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"); - qInstallMessageHandler(qMessageOutput);
- }
LogViewer.h
- #ifndef LOGVIEWER_H
- #define LOGVIEWER_H
-
- #include
-
- 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_H
LogViewer.cpp
connect到MsgHandlerWapper实例的message信号
设置前景与背景改变颜色
- #include "LogViewer.h"
- #include "ui_LogViewer.h"
- #include
- #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();
- }