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);
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM