Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.
Browser for QDebug output: Difference between revisions
AutoSpider (talk | contribs) (Add "cleanup" tag) |
AutoSpider (talk | contribs) (Decode HTML entity names) |
||
Line 44: | Line 44: | ||
public slots: | public slots: | ||
void outputMessage( QtMsgType type, const QString & | void outputMessage( QtMsgType type, const QString &msg ); | ||
signals: | signals: | ||
void sendMessage( QtMsgType type, const QString & | void sendMessage( QtMsgType type, const QString &msg ); | ||
private: | private: | ||
Line 81: | Line 81: | ||
} | } | ||
void LogBrowser::outputMessage(QtMsgType type, const QString & | void LogBrowser::outputMessage(QtMsgType type, const QString &msg) | ||
{ | { | ||
emit sendMessage( type, msg ); | emit sendMessage( type, msg ); | ||
Line 108: | Line 108: | ||
public slots: | public slots: | ||
void outputMessage( QtMsgType type, const QString & | void outputMessage( QtMsgType type, const QString &msg ); | ||
protected slots: | protected slots: | ||
Line 178: | Line 178: | ||
void LogBrowserDialog::outputMessage(QtMsgType type, const QString & | void LogBrowserDialog::outputMessage(QtMsgType type, const QString &msg) | ||
{ | { | ||
switch (type) { | switch (type) { | ||
Line 223: | Line 223: | ||
} | } | ||
QTextStream stream(& | QTextStream stream(&file); | ||
stream << browser->toPlainText(); | stream << browser->toPlainText(); | ||
file.close(); | file.close(); |
Revision as of 16:55, 12 March 2015
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine. Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean. |
English | Deutsch
[toc align_right="yes" depth="4"]
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;
class LogBrowser : public QObject
{
Q_OBJECT
public:
explicit LogBrowser(QObject *parent = 0);
~LogBrowser();
public slots:
void outputMessage( QtMsgType type, const QString &msg );
signals:
void sendMessage( QtMsgType type, const QString &msg );
private:
LogBrowserDialog *browserDialog;
};
#endif // LOGBROWSER_H
logbrowser.cpp
#include "logbrowser.h"
#include <QMetaType>
#include "logbrowserdialog.h"
LogBrowser::LogBrowser(QObject *parent) :
QObject(parent)
{
qRegisterMetaType<QtMsgType>("QtMsgType");
browserDialog = new LogBrowserDialog;
connect(this, SIGNAL (sendMessage(QtMsgType,QString)), browserDialog, SLOT (outputMessage(QtMsgType,QString)), Qt::QueuedConnection);
browserDialog->show();
}
LogBrowser::~LogBrowser()
{
delete browserDialog;
}
void LogBrowser::outputMessage(QtMsgType type, const QString &msg)
{
emit sendMessage( type, msg );
}
logbrowserdialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
class QTextBrowser;
class QPushButton;
class LogBrowserDialog : public QDialog
{
Q_OBJECT
public:
LogBrowserDialog(QWidget *parent = 0);
~LogBrowserDialog();
public slots:
void outputMessage( QtMsgType type, const QString &msg );
protected slots:
void save();
protected:
virtual void keyPressEvent( QKeyEvent *e );
virtual void closeEvent( QCloseEvent *e );
QTextBrowser *browser;
QPushButton *clearButton;
QPushButton *saveButton;
};
#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>
LogBrowserDialog::LogBrowserDialog(QWidget *parent)
: QDialog(parent)
{
QVBoxLayout *layout = new QVBoxLayout;
setLayout(layout);
browser = new QTextBrowser(this);
layout->addWidget(browser);
QHBoxLayout '''buttonLayout = new QHBoxLayout;
buttonLayout->setContentsMargins(0, 0, 0, 0);
layout->addLayout(buttonLayout);
buttonLayout->addStretch(10);
clearButton = new QPushButton(this);
clearButton->setText("clear");
buttonLayout->addWidget(clearButton);
connect(clearButton, SIGNAL (clicked()), browser, SLOT (clear()));
saveButton = new QPushButton(this);
saveButton->setText("save output");
buttonLayout->addWidget(saveButton);
connect(saveButton, SIGNAL (clicked()), this, SLOT (save()));
resize(200, 400);
}
LogBrowserDialog::~LogBrowserDialog()
{
}
void LogBrowserDialog::outputMessage(QtMsgType type, const QString &msg)
{
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()
{
QString saveFileName = QFileDialog::getSaveFileName(
this,
tr("Save Log Output"),
tr("%1/logfile.txt").arg(QDir::homePath()),
tr("Text Files ('''.txt);;All Files (*)")
);
if(saveFileName.isEmpty())
return;
QFile file(saveFileName);
if(!file.open(QIODevice::WriteOnly)) {
QMessageBox::warning(
this,
tr("Error"),
QString(tr("<nobr>File '%1'<br/>cannot be opened for writing.<br/><br/>"
"The log output could <b>not</b> be saved!</nobr>"))
.arg(saveFileName));
return;
}
QTextStream stream(&file);
stream << browser->toPlainText();
file.close();
}
void LogBrowserDialog::closeEvent(QCloseEvent *e)
{
QMessageBox::StandardButton answer = QMessageBox::question(
this,
tr("Close Log Browser?"),
tr("Do you really want to close the log browser?"),
QMessageBox::Yes | QMessageBox::No
);
if (answer == QMessageBox::Yes)
e->accept();
else
e->ignore();
}
void LogBrowserDialog::keyPressEvent(QKeyEvent *e)
{
// 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"
QPointer<LogBrowser> logBrowser;
void myMessageOutput(QtMsgType type, const char *msg)
{
if(logBrowser)
logBrowser->outputMessage( type, msg );
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
logBrowser = new LogBrowser;
qInstallMsgHandler(myMessageOutput);
qDebug() << "test for debug";
int result = a.exec();
qDebug() << "application exec return result =" << result;
delete logBrowser;
return result;
}