Qt调试信息重定向输出(qInstallMessageHandler)

由于工具需要,做了一小段Qt5测试代码,参考了网友的案例测试了以下功能

 

1 qDebug()重定向输出QT窗口

2 qDebug()信息保存到本地文件

QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)

  此函数在使用Qt消息处理程序之前已定义。返回一个指向前一个消息处理程序。
  消息处理程序是一个函数,用于打印qDebug,qWarning,qCritical和qFatal的错误消息。Qt库(调试模块)包含成百上千的警告信息,打印时(通常是无效的函数参数)发生内部错误。Qt构建在release模式下还包含一些除了QT_NO_WARNING_OUTPUT和/或QT_NO_DEBUG_OUTPUT之外的警告已经设置在编译。如果你实现自己的消息处理程序,需要完全控制这些消息。
  在X11或Windows下的调试器,缺省的消息处理程序向标准输出打印消息。如果这是一个致命的消息,应用程序立即中止。
  只有一个消息处理程序可以被定义,因为这通常是在应用程序的基础上完成控制调试输出。
  恢复消息处理程序,调用qInstallMessageHandler(0)。

注意: 

QT4: qInstallMsgHandler()

QT5: qInstallMessageHandler()

参考1: https://www.cnblogs.com/wyuzm/p/9580447.html

参考2: https://blog.csdn.net/lbsljn/article/details/73804445?utm_source=blogxgwz0

TextBrower常用窗口组件说明:https://www.xuebuyuan.com/3179243.html

https://forum.qt.io/topic/68873/how-to-navigate-qplaintextedit-qtextbrowser

#include <QApplication>
#include <QPointer>
#include <QVariant>
#include <QtCore/QVariant>
#include <QDebug>

QPointer<Widget> log_broswer;
void outputMsg(QtMsgType type, const QMessageLogContext&, const QString& str) {
    log_broswer->outputMsg( type, str);
}

int main(int argc, char *argv[]) {

    QApplication a(argc, argv);
    log_broswer = new Widget;
    log_broswer->show();
    qDebug() << "hello Qt";
    qInstallMessageHandler(outputMsg);
    int result = a.exec();
    delete log_broswer;
    return result;
}

#include <QWidget>
#include <QCloseEvent>
//#include <QDialog>
#include <QDir>
#include <QFileSystemWatcher>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QProcess>
#include <QPushButton>
#include <QTextBrowser>
#include <QTimer>
#include <QVBoxLayout>
#include <QFileSystemWatcher>
#include <QPlainTextEdit>
#include <QMutex>

#include <QtDebug>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
     Q_OBJECT

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

    void outputMsg(QtMsgType type, const QString &msg);

  public slots:
    void start();
    void save(bool enable);
    //path for monitor
    void dirUpdated(const QString &path);
  private slots:

    void on_pushButton_start_clicked();
    void on_pushButton_stop_clicked();
    void on_pushButton_save_clicked();
    void on_pushButton_exit_clicked();
    void readCmdInformation();
    void autoUpdata();
    void on_pushButton_update_clicked();
    void displayUdiskFileList();

private:
 // public:
    Ui::Widget *ui;
    QTextBrowser *browser;
    QPlainTextEdit *plainTextEdit;
    QPushButton *start_button;
    QPushButton *stop_button;
    QProcess *my_process;
    QFileSystemWatcher *my_sysWatcher;
    QTimer *my_timer;
    bool is_finished;
    bool my_saveEnable;
};

#endif // WIDGET_H

Widget::Widget(QWidget *parent) :QWidget(parent),
                              ui(new Ui::Widget) {
    ui->setupUi(this);
    my_timer = new QTimer();
    my_process = new QProcess();  //zhi xing mingling process
    //if thereis output it will send out msg, receive can accept input msg
    connect(my_process, SIGNAL(readyRead()), this, SLOT(readCmdInformation));

    my_sysWatcher = new QFileSystemWatcher();
    my_sysWatcher->addPath("/data");   //monitor file path
   //triger when file change
    connect(my_sysWatcher,
            SIGNAL(directoryChanged(QString)),
            this,
            SLOT(dirUpdated(QString)));


    is_finished = false;
    my_saveEnable = false;
    qDebug()<<" init widget ";
}

//read info form command line to self window
void Widget::readCmdInformation() {
    QString str = my_process->readAllStandardOutput();
    ui->plainTextEdit->appendPlainText(str);
    ui->plainTextEdit->moveCursor(QTextCursor::End);
}

//open swithch save all info to log.txt
void Widget::save(bool enable)
{
   my_saveEnable = enable;

}
//test scipt can remove it if necessary
void Widget::start() {

    qDebug("start %d  !" ,is_finished);
    for (int i = 0; i < 1000000; i++) {
        if (!is_finished) {
            QCoreApplication::processEvents();
            qDebug() << QString("qDebug::").append(QString::number(i, 10));
        } else {
            return;
        }
    }
}
//auto update  auto exec script
void Widget::autoUpdata()
{
    ui->plainTextEdit->appendPlainText("auto update start \n");
   // my_process->start("/mnt/sda1/auto.sh");
}
void Widget::on_pushButton_start_clicked()
{
    is_finished = false;
    qDebug()<<"start click !";
    this->start();

}
//show dir in u disk , need delay for mount
void Widget::displayUdiskFileList()
{
    const QDir udir("/mnt/sda1");
    QStringList uDiskList = udir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files);
    ui->plainTextEdit->appendPlainText(QString().setNum(uDiskList.length()));
    for(int i =0; i<uDiskList.length();++i)
    {
        ui->plainTextEdit->appendPlainText(uDiskList[1]);

    }

}

void Widget::on_pushButton_stop_clicked()
{
    is_finished = true;
}
void Widget::on_pushButton_exit_clicked()
{
    this->close();
    delete this; //key point
}

void Widget::on_pushButton_update_clicked()
{
  this->autoUpdata();
}

void Widget::on_pushButton_save_clicked()
{
   this->save(true);
}
//get debug or warning msg
void Widget::outputMsg(QtMsgType type, const QString &msg) {
    QString message;

    static QMutex mutex;
    mutex.lock();
    switch(type) {

    case QtDebugMsg:
        message = QString("Debug:");
        break;

    case QtWarningMsg:
        message = QString("Warning:");
        break;

    case QtCriticalMsg:
        message = QString("Critical:");
        break;

    case QtFatalMsg:
        message = QString("Fatal:");
        break;

    }
    ui->plainTextEdit->appendPlainText(message.append(msg));
 //    qDebug()<< "go to here1\n";
     ui->plainTextEdit->moveCursor(QTextCursor::End); //滑动条移动到底端
 //   std::cout<<"wait";
     if (my_saveEnable) {
            QFile file("log.txt");
            file.open(QIODevice::WriteOnly | QIODevice::Append);
            QTextStream text_stream(&file);
            text_stream << message << "\r\n";
            file.flush();
            file.close();
       }
     mutex.unlock();

}
void Widget::dirUpdated(const QString &path) {
    const QDir dir(path);
    QStringList newEntryList = dir.entryList(
        QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files, QDir::DirsFirst);

    if (newEntryList.contains("sda1")) {
          ui->plainTextEdit->setPlainText("U disk has been mounted");
        emit my_timer->singleShot(2000, this, SLOT(displayUdiskFileList()));
          ui->pushButton_update->setEnabled(true);
    } else {
         ui->plainTextEdit->setPlainText("U disk has been unmounted");
         ui->pushButton_update->setEnabled(false);
    }
}
posted @ 2019-12-25 23:53  七星望  阅读(1831)  评论(0编辑  收藏  举报