QT日志调试系统(前台、后台、文件查看调试信息)

QT日志调试系统(前台、后台、文件查看调试信息)_第1张图片
通过qInstallMessageHandler获取Qt的打印信息,将这些打印信息存放到一个Widget中,实现不通过后台就能查看日志信息。
实现方法如下:
main.cpp

#include "mainwidget.h"
#include <QApplication>
#include <QStyleFactory>
#include "logwidget.h"

void logOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    LogWidget::instance()->myMessageOutput(type,context,msg);
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QApplication::setStyle(QStyleFactory::create("Fusion"));

    bool ok = false;
    QSharedMemory sharedMemory("testApp");
    if (sharedMemory.attach(QSharedMemory::ReadOnly))
    {
        sharedMemory.detach();
    }

    if (sharedMemory.create(1))
    {
        LogWidget::instance()->show();
        qInstallMessageHandler(logOutput);
        MainWidget w;
        w.move(0,0);
        w.show();

        ok = a.exec();
        if (sharedMemory.isAttached())
            sharedMemory.detach();
    }

    return ok;
}

以下代码中记录了前台、后台、文件查看调试信息
logwidget.cpp

#include "logwidget.h"
#include <QDateTime>
#include <QApplication>
#include <QDir>
#include <QTextStream>
#include <QHBoxLayout>

QMutex LogWidget::m_mutex;
LogWidget* LogWidget::m_Instance = nullptr;

LogWidget::LogWidget(QWidget *parent) :
    QWidget(parent)
{
    this->setWindowFlags(Qt::WindowStaysOnTopHint|Qt::WindowCloseButtonHint|Qt::WindowMaximizeButtonHint);
    m_textEdit = new QTextEdit(this);
    QHBoxLayout* lay = new QHBoxLayout(this);
    lay->addWidget(m_textEdit);
    this->setLayout(lay);

    connect(this,&LogWidget::sig_logUpdate,this,[&](QString msg)
    {
        m_textEdit->append(msg);
    });
}

LogWidget::~LogWidget()
{
}

LogWidget *LogWidget::instance()
{
    if (m_Instance == NULL)
    {
        m_mutex.lock();
        if (m_Instance == NULL)
        {
            m_Instance = new LogWidget();
        }
        m_mutex.unlock();
    }
    return m_Instance;
}

void LogWidget::myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
#if 1
    // 加锁
    static QMutex mutex;
    mutex.lock();

    QByteArray localMsg = msg.toLocal8Bit();

    QString strMsg("");
    switch(type)
    {
    case QtDebugMsg:
        strMsg = QString("Debug:");
        break;
    case QtWarningMsg:
        strMsg = QString("Warning:");
        break;
    case QtCriticalMsg:
        strMsg = QString("Critical:");
        break;
    case QtFatalMsg:
        strMsg = QString("Fatal:");
        break;
    }

    // 设置输出信息格式
    QString strDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QString strMessage = QString("DateTime:%1:%2 \t\t(line:%3) (File:%4)").arg(strDateTime)
            .arg(localMsg.constData()).arg(context.line).arg(context.file);

    //打印输出窗口显示调试信息
    fprintf(stderr, "%s\n", strMessage.toLatin1().data());
    //前台Widget显示调试信息
    emit sig_logUpdate(strMessage);
    // 输出调试信息至文件中(读写、追加形式)
    QDir dir(QApplication::applicationDirPath()+"/log");
    if (!dir.exists())
        dir.mkpath(dir.path());
    QString logName = dir.path() + "/log_"+QDate::currentDate().toString("yyyy-MM-dd")+".txt";
    QFile file(logName);
    file.open(QIODevice::ReadWrite | QIODevice::Append);
    QTextStream stream(&file);
    stream << strMessage << "\r\n";
    file.flush();
    file.close();

    // 解锁
    mutex.unlock();
#endif
}

logwidget.h

#ifndef LOGWIDGET_H
#define LOGWIDGET_H

#include <QWidget>
#include <QTextEdit>
#include <QMutex>

class LogWidget : public QWidget
{
    Q_OBJECT

public:
    ~LogWidget();
    static LogWidget *instance();
    void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);

signals:
    void sig_logUpdate(QString msg);
private:
    explicit LogWidget(QWidget *parent = nullptr);
    static QMutex m_mutex;
    static LogWidget* m_Instance;
    QTextEdit* m_textEdit = nullptr;
};

#endif // LOGWIDGET_H

你可能感兴趣的:(QT,qt,开发语言)