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

浙公网安备 33010602011771号