Browser for QDebug output/de

From Qt Wiki
< Browser for QDebug output
Revision as of 16:55, 12 March 2015 by AutoSpider (talk | contribs) (Decode HTML entity names)
Jump to navigation Jump to search
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.

Deutsch | English

[toc align_right="yes" depth="4"]

Ein Browser für QDebug-Log-Ausgaben

Der folgende Code-Schnipsel zeigt, wie man einen einfachen Log-Browser zu einem Programm hinzufügen kann.

Der Schnipsel besteht aus dem eigentlichen Log-Browser (Klasse LogBrowserDialog in logbrowserdialog.h und logbrowserdialog.h) und einem kleinen Wrapper (Klasse LogBrowser in logbrowser.h und logbrowser.h). Der Wrapper wird in der

main()

-Funktion des Programms instantiiert und erzeugt das Browser-Fenster. Er fungiert darüber hinaus auch als Zwischenstück und wandelt die const char* -basierten Nachrichten des Debug-Systems in QString-basierte Nachrichten. Mit diesem Trick können die Debug-Nachrichten an den eigentlichen Browser mittels Signal-Slot-Verbindungen gesendet werden. Dadurch kann der Browser auch in einem Programm mit mehreren Threads verwendet werden.

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