QDebug 日志输出的浏览器

实现功能


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_H

MsgHandlerWapper.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_H

LogViewer.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版权协议,转载请附上原文出处链接和本声明。