Table of Content
A Browser for QDebug Log Output
The code on this page shows how a simple log browser can be added to an application.
It consists of the actual log browser (class LogBrowserDialog in logbrowserdialog.h and logbrowserdialog.h) and a small wrapper (class LogBrowser in logbrowser.h and logbrowser.h). The wrapper is instantiated in the main function of an application and creates the browser window. It also acts as an intermediary and converts the const char * based messages from the debug system into QString based messages. With this trick the debug messages can be sent to the actual browser by the means of signal/slot connections. This adds basic thread support to the browser.
logbrowser.pro
- QT += core gui
- TARGET = DebugWindow
- TEMPLATE = app
- SOURCES += main.cpp logbrowserdialog.cpp logbrowser.cpp
- HEADERS += logbrowserdialog.h logbrowser.h
logbrowser.h
- #ifndef LOGBROWSER_H
- #define LOGBROWSER_H
- #include <QObject>
- class LogBrowserDialog;
- {
- Q_OBJECT
- public:
- ~LogBrowser();
- public slots:
- signals:
- private:
- LogBrowserDialog *browserDialog;
- };
- #endif // LOGBROWSER_H
logbrowser.cpp
- #include "logbrowser.h"
- #include <QMetaType>
- #include "logbrowserdialog.h"
- {
- qRegisterMetaType<QtMsgType>("QtMsgType");
- browserDialog = new LogBrowserDialog;
- browserDialog->show();
- }
- LogBrowser::~LogBrowser()
- {
- delete browserDialog;
- }
- {
- emit sendMessage( type, msg );
- }
logbrowserdialog.h
- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QDialog>
- class QTextBrowser;
- class QPushButton;
- {
- Q_OBJECT
- public:
- ~LogBrowserDialog();
- public slots:
- protected slots:
- void save();
- protected:
- };
- #endif // DIALOG_H
logbrowserdialog.cpp
- #include "logbrowserdialog.h"
- #include <QVBoxLayout>
- #include <QHBoxLayout>
- #include <QTextBrowser>
- #include <QPushButton>
- #include <QFileDialog>
- #include <QDir>
- #include <QFile>
- #include <QMessageBox>
- #include <QTextStream>
- #include <QCloseEvent>
- #include <QKeyEvent>
- {
- setLayout(layout);
- layout->addWidget(browser);
- buttonLayout->setContentsMargins(0, 0, 0, 0);
- layout->addLayout(buttonLayout);
- buttonLayout->addStretch(10);
- clearButton->setText("clear");
- buttonLayout->addWidget(clearButton);
- connect(clearButton, SIGNAL(clicked()), browser, SLOT(clear()));
- saveButton->setText("save output");
- buttonLayout->addWidget(saveButton);
- connect(saveButton, SIGNAL(clicked()), this, SLOT(save()));
- resize(200, 400);
- }
- LogBrowserDialog::~LogBrowserDialog()
- {
- }
- {
- switch (type) {
- case QtDebugMsg:
- browser->append(msg);
- break;
- case QtWarningMsg:
- browser->append(tr("-- WARNING: %1").arg(msg));
- break;
- case QtCriticalMsg:
- browser->append(tr("-- CRITICAL: %1").arg(msg));
- break;
- case QtFatalMsg:
- browser->append(tr("-- FATAL: %1").arg(msg));
- break;
- }
- }
- void LogBrowserDialog::save()
- {
- this,
- tr("Save Log Output"),
- tr("Text Files (*.txt);;All Files (*)")
- );
- if(saveFileName.isEmpty())
- return;
- this,
- tr("Error"),
- "The log output could <b>not</b> be saved!</nobr>"))
- .arg(saveFileName));
- return;
- }
- stream << browser->toPlainText();
- file.close();
- }
- {
- this,
- tr("Close Log Browser?"),
- tr("Do you really want to close the log browser?"),
- );
- e->accept();
- else
- e->ignore();
- }
- {
- // ignore all keyboard events
- // protects against accidentally closing of the dialog
- // without asking the user
- e->ignore();
- }
main.cpp
- #include <QApplication>
- #include <QPointer>
- #include <QDebug>
- #include "logbrowser.h"
- void myMessageOutput(QtMsgType type, const char *msg)
- {
- if(logBrowser)
- logBrowser->outputMessage( type, msg );
- }
- int main(int argc, char *argv[])
- {
- logBrowser = new LogBrowser;
- qInstallMsgHandler(myMessageOutput);
- qDebug() << "test for debug";
- int result = a.exec();
- qDebug() << "application exec return result =" << result;
- delete logBrowser;
- return result;
- }

