[英]Redirect qDebug to an emitted signal
我已經成功將qDebug()
輸出重定向到QTextEdit
小部件。 由於多種原因,我希望每個qDebug()
消息都包含在發出的信號中。 原因之一是應接收輸出的對象不可用。 另一個原因是,我想根據當前活動處於活動狀態(使用信號到不同插槽的連接/斷開連接)將輸出重定向到不同的對象。
我編寫了一個有效的示例代碼,將qDebug
重定向到QTextEdit
小部件。 有人可以幫我獲取此代碼以發出包含qDebug
消息的信號嗎?
我不確定是否有可能讓Q_DebugStream
發出一個信號(我嘗試過但未能使它成為Qt類)。
調用Q_DebugStream
,必須有可能傳遞指向函數/插槽的指針,而不是指向QTextEdit
的指針,但是我不確定如何做到這一點。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void logSignal(QString);
public slots:
void logSlot(QString);
private:
QTextEdit *logView;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "q_debugstream.h"
#include <QGridLayout>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget *mainWidget = new QWidget(this);
setCentralWidget(mainWidget);
logView = new QTextEdit;
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(logView,0,0,1,1);
mainWidget->setLayout(mainLayout);
connect(this, SIGNAL(logSignal(QString)),
this, SLOT(logSlot(QString)));
emit logSignal("Message from a signal\n");
new Q_DebugStream(std::cout, logView); //Redirect Console output to QTextEdit
Q_DebugStream::registerQDebugMessageHandler(); //Redirect qDebug() output to QTextEdit
qDebug() << "DEBUG MODE ACTIVE";
}
MainWindow::~MainWindow(){}
void MainWindow::logSlot(QString log) {
logView->append(log);
}
//As per forum:
//http://www.qtforum.org/article/39768/redirecting-std-cout-std-cerf-qdebug-to-qtextedit.html
//A couple of lines added to ensure newlines go between each call.
//Thanks, James!
#ifndef Q_DEBUGSTREAM_H
#define Q_DEBUGSTREAM_H
#include <iostream>
#include <streambuf>
#include <string>
#include <QTextEdit>
class Q_DebugStream : public std::basic_streambuf<char>
{
public:
Q_DebugStream(std::ostream &stream, QTextEdit* text_edit) : m_stream(stream)
{
log_window = text_edit;
m_old_buf = stream.rdbuf();
stream.rdbuf(this);
}
~Q_DebugStream()
{
m_stream.rdbuf(m_old_buf);
}
static void registerQDebugMessageHandler(){
qInstallMessageHandler(myQDebugMessageHandler);
}
private:
static void myQDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &msg)
{
std::cout << msg.toStdString().c_str();
}
protected:
//This is called when a std::endl has been inserted into the stream
virtual int_type overflow(int_type v)
{
if (v == '\n')
{
log_window->append("");
}
return v;
}
virtual std::streamsize xsputn(const char *p, std::streamsize n)
{
QString str(p);
if(str.contains("\n")){
QStringList strSplitted = str.split("\n");
log_window->moveCursor (QTextCursor::End);
log_window->insertPlainText (strSplitted.at(0)); //Index 0 is still on the same old line
for(int i = 1; i < strSplitted.size(); i++){
log_window->append(strSplitted.at(i));
log_window->append("\n");
}
}else{
log_window->moveCursor (QTextCursor::End);
log_window->insertPlainText (str);
log_window->insertPlainText ("\n");
}
return n;
}
private:
std::ostream &m_stream;
std::streambuf *m_old_buf;
QTextEdit* log_window;
};
#endif // Q_DEBUGSTREAM_H
啟動應用程序時,我在QTextEdit中收到兩條消息:
"Message from a signal"
"DEBUG MODE ACTIVE"
(此答案是從對問題的編輯中提取的-現在已回滾)。
這是我解決此問題的方法:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void logSignal(QString);
public slots:
void logSlot(QString);
private:
void dbgMsg(QString);
QTextEdit *logView;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "q_debugstream.h"
#include <QGridLayout>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget *mainWidget = new QWidget(this);
setCentralWidget(mainWidget);
logView = new QTextEdit;
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(logView,0,0,1,1);
mainWidget->setLayout(mainLayout);
connect(this, SIGNAL(logSignal(QString)),
this, SLOT(logSlot(QString)));
emit logSignal("Now call Q_DebugStream");
//Redirect qDebug() output to dbgMsg(QString)
new Q_DebugStream(std::cout, this, &MainWindow::dbgMsg);
Q_DebugStream::registerQDebugMessageHandler();
qDebug() << "Debug message";
qWarning() << "Warning!";
qCritical() << "Critical issue!";
qInfo() << "Information";
qDebug() << "This\nis\na\nlong\none.";
}
MainWindow::~MainWindow(){}
void MainWindow::logSlot(QString log) {
logView->append(log);
}
void MainWindow::dbgMsg(QString log) {
emit logSignal(log);
}
#ifndef Q_DEBUGSTREAM_H
#define Q_DEBUGSTREAM_H
#include <iostream>
#include <streambuf>
#include <string>
#include <QString>
#include "mainwindow.h"
class Q_DebugStream : public std::basic_streambuf<char> {
public:
Q_DebugStream(std::ostream &stream, MainWindow* obj, void (MainWindow::*dbgMsgPtr)(QString log)): m_stream(stream) {
m_old_buf = stream.rdbuf();
stream.rdbuf(this);
msgObj = obj;
msgHandler = dbgMsgPtr;
}
~Q_DebugStream() {
m_stream.rdbuf(m_old_buf);
}
static void registerQDebugMessageHandler() {
qInstallMessageHandler(myQDebugMessageHandler);
}
private:
static void myQDebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
QString message = msg;
switch (type) {
case QtDebugMsg:
message.prepend("qDbg(): ");
break;
case QtWarningMsg:
message.prepend("qWarn(): ");
break;
case QtCriticalMsg:
message.prepend("qCrit(): ");
break;
case QtInfoMsg:
message.prepend("qInfo(): ");
break;
case QtFatalMsg:
message.prepend("qFatal(): ");
abort();
break;
}
message.append(" (" + QString::fromUtf8(context.file) + ")");
message.append(" line: " + QString::number(context.line));
std::cout << message.toStdString().c_str();
}
protected:
//This is called when a std::endl has been inserted into the stream
virtual int_type overflow(int_type v) {
if (v == '\n') {
(msgObj->*msgHandler)("\n");
}
return v;
}
virtual std::streamsize xsputn(const char *p, std::streamsize n) {
QString str(p);
if(str.contains("\n")) {
QStringList strSplitted = str.split("\n");
(msgObj->*msgHandler)(strSplitted.at(0)); //Index 0 is still on the same old line
for(int i = 1; i < strSplitted.size(); i++) {
(msgObj->*msgHandler)("\\ " + strSplitted.at(i));
}
} else {
(msgObj->*msgHandler)(str);
}
return n;
}
private:
std::ostream &m_stream;
std::streambuf *m_old_buf;
MainWindow* msgObj;
void (MainWindow::*msgHandler)(QString);
};
#endif // Q_DEBUGSTREAM_H
當應用程序啟動時,我在QTextEdit中得到以下消息:
Now call Q_DebugStream
qDbg(): Debug message (..\qDebugFetch\mainwindow.cpp) line: 25
qWarn(): Warning! (..\qDebugFetch\mainwindow.cpp) line: 26
qCrit(): Critical issue! (..\qDebugFetch\mainwindow.cpp) line: 27
qInfo(): Information (..\qDebugFetch\mainwindow.cpp) line: 28
qDbg(): This
\ is
\ a
\ long
\ one. (..\qDebugFetch\mainwindow.cpp) line: 29
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.