Qt日志重定向至界面控件QTextEdit的一种方法

概述

Qt开发过程中经常需要输出调试日志,这些日志分为五个级别:qDebug、qWarning、qInfo、qCritical、qFatal。这些日志在调试过程中我们可以在开发工具的程序输出窗口查看,而实际使用的release版本脱离开发环境后则没办法显示这些信息。如果能在release版本中也将这些信息打印出来的话就可以方便后续程序维护及bug定位。

将日志信息重定向输出到txt文件中是一种不错的方法,实现也比较简单,但是需要去相应路径打开文件查看,不够直观。如果想实时查看输出日志的话可以将日志重定向输出到界面控件QTextEdit上,并且根据日志类别控制信息显示的颜色,本文提供这样一种实现手段。效果如下图所示

实现原理

1.qInstallMsgHandler函数用于安装之前定义的Qt消息处理程序。返回指向上一个消息处理程序的指针,其函数原型为:

QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)

2.在myMessageOutput函数中将调试信息及信息类型(组合成结构体LogElement)输出至一个缓冲区队列中。

3.界面上设置定时读取队列数据显示在QTextEdit中,根据信息类型控制该行信息的颜色,实现代码如下。

main.cpp

#include "mainwindow.h"
#include <QApplication>

void LogMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    static QMutex mutex;
    Q_UNUSED(context);
    mutex.lock();
    QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz");
    QString message = QString("%1  %2\r\n").arg(current_date_time).arg(msg);
    LogElement log_element={type,message};
    log_txt.enqueue(log_element);
    mutex.unlock();
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    qInstallMessageHandler(LogMessage);
    qDebug()<<"startup application!";
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#define RED     QColor(192,0,0)
#define GREEN   QColor(0,192,0)
#define YELLOW  QColor(192,192,0)
#define BLACK   QColor(0,0,0)
#define GRAY    QColor(128,128,128)

typedef struct{
    QtMsgType type;
    QString txt;
}LogElement;
extern QQueue<LogElement> log_txt;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_Timer0Timeout();
    
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

private:
    Ui::MainWindow *ui;
    QTimer *timer0;

};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

QQueue<LogElement> log_txt;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);;

    timer0=new QTimer(this);
    timer0->setInterval(100);
    connect(timer0,&QTimer::timeout,this,&MainWindow::on_Timer0Timeout);
    timer0->start();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_Timer0Timeout()
{
    QTextCharFormat tcf;
    while(log_txt.count()){
        LogElement log_element=log_txt.dequeue();
        switch (log_element.type) {
        case QtMsgType::QtInfoMsg:
            tcf.setForeground(Qt::blue);
            break;
        case QtMsgType::QtWarningMsg:
            tcf.setForeground(Qt::red);
            break;
        default:
            tcf.setForeground(Qt::black);
            break;
        }
        ui->textEdit->moveCursor(QTextCursor::End);
        ui->textEdit->textCursor().insertText(log_element.txt,tcf);
    }
}

void MainWindow::on_pushButton_clicked()
{
    qDebug()<<"提示:消息1!";
}

void MainWindow::on_pushButton_2_clicked()
{
    qInfo()<<"警告:消息2!";
}

void MainWindow::on_pushButton_3_clicked()
{
    qWarning()<<"错误:消息3!";
}

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在PyQt5中,可以使用QTextEdit控件将print输出重定向界面上。 首先,我们需要导入必要的模块,包括PyQt5和sys: ```python from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QTextEdit import sys ``` 接下来,我们创建一个自定义的QWidget类,用于承载界面。在该类中,我们创建一个QTextEdit控件,并将其设置为只读: ```python class MainWindow(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): layout = QVBoxLayout(self) self.textEdit = QTextEdit(self) self.textEdit.setReadOnly(True) layout.addWidget(self.textEdit) self.setLayout(layout) def write(self, text): self.textEdit.moveCursor(QtGui.QTextCursor.End) self.textEdit.insertPlainText(text) ``` 在上述代码中,我们重写了QWidget类的write()方法,该方法会在print时被调用。我们将插入的文本追加到QTextEdit中已有的文本末尾。 接下来,我们重定向print输出到我们创建的QWidget子类实例的write()方法中。这样,所有的print输出都会被重定向界面上: ```python app = QApplication(sys.argv) window = MainWindow() sys.stdout = window sys.stderr = window print("Hello PyQt5!") window.show() sys.exit(app.exec_()) ``` 最后,我们运行应用程序,并创建一个MainWindow实例。然后,将sys.stdout和sys.stderr重定向到我们自定义QWidget子类的实例中。这样,print输出就会被重定向到我们的界面中。 在上述例子中,我们输出了一条print语句"Hello PyQt5!",该输出会被重定向到我们的界面中的QTextEdit控件中。 总结起来,要实现将print输出重定向到PyQt5界面,我们需要创建一个带有QTextEdit控件的QWidget子类,并重写其write()方法,然后将sys.stdout和sys.stderr重定向到该QWidget子类的实例上。这样,所有的print输出就会被重定向界面上。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值