Is it possible (and more importantly -how-) to redirect an output stream to a QTextBox. So that if I write std::cout << "test"
anywhere in the application it gets redirected to a textbox I defined?
I tried the obvious (where ui.textEdit is a pointer to the text edit box):
std::cout.rdbuf(ui.textEdit);
std::cout << "test";
However this doesn't work. (obviously). - Nor does redirecting cout to qDebug work (or even direction a qDebug to a textfield).
I'm using qt4.8 btw...
EDIT: So I tried the solution posted in the mailing list.. However now an access violation shows up.
class MainInterface : public QMainWindow
{
Q_OBJECT
....
private:
QDebugStream qout
With the constructor:
MainInterface::MainInterface(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags),
qout(std::cout, ui.textEdit)
{
And in a member function the following line is posted: std::cout << "Project Loaded" << std::endl;
That line now causes an access violation from "qscoped_pointer". (Should I post this with more detail as seperate question?)
EDIT: well the "solution" was to only declare qout after the ui.textEdit was fully created.
I wrote my own function for this problem , for a QTextEdit, just be aware that if you run it with heavy operations along the main Thread your GUI will freeze. So you have to instantiate a new QThread for example then the GUI respectively the QTextEdit will be updated accordingly:
Header File:
class myConsoleStream : public std::basic_streambuf<char>
{
public:
myConsoleStream(std::ostream &stream, QTextEdit* text_edit);
virtual ~myConsoleStream();
static void registerMyConsoleMessageHandler();
private:
static void myConsoleMessageHandler(QtMsgType type, const QMessageLogContext &, const QString &msg);
protected:
// Diese Funktion wird aufgerufen wenn std::endl im Stream erscheint
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);
private:
std::ostream &m_stream;
std::streambuf *m_old_buf;
QTextEdit* log_window;
};
#endif // Q_DEBUGSTREAM_H
.cpp File:
myConsoleStream::myConsoleStream(std::ostream &stream, QTextEdit* text_edit)
:std::basic_streambuf<char>()
,m_stream(stream)
{
this->log_window = text_edit;
this->m_old_buf = stream.rdbuf();
stream.rdbuf(this);
}
myConsoleStream::~myConsoleStream()
{
this->m_stream.rdbuf(this->m_old_buf);
}
void myConsoleStream::registerMyConsoleMessageHandler()
{
qInstallMessageHandler(myConsoleMessageHandler);
}
void myConsoleStream::myConsoleMessageHandler(QtMsgType type, const QMessageLogContext &, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
switch (type) {
case QtDebugMsg:
// fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtInfoMsg:
// fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtWarningMsg:
// fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtCriticalMsg:
//fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtFatalMsg:
// fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
default:
std::cout << msg.toStdString().c_str();
break;
}
}
In your mainwindow you just have to instantiate your new Stream :
new myConsoleStream(std::cout, this->ui->Console);
myConsoleStream::registerMyConsoleMessageHandler();
and you are good too go! Hope this helps.
You could reset cout
to your own ostream
implementation which would emit
signals which you hook onto the append
slot. You sub-problems/exercises are therefore:
cout
cout
to your own ostream
implementation or one that you can extendemit
signals to QTextBox
These sub-topics are available on SO, as far as I know
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With