Search code examples
c++qtc++11qt5.5

QTextEdit promoted to Construct a Console Window


I try to construct a promoted QTextEdit Console widget for my Gui in which i redirect all std::cout. For the redirection i mostly followed this tutorial:

My code looks like this: myConsoleStream.cpp:

#include "myconsolestream.h"    

myConsoleStream::myConsoleStream(std::ostream &stream, QTextEdit* text_edit,QWidget *parent)
    :std::basic_streambuf<char>()
    ,m_stream(stream)
    ,myConsole(parent)

{
    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, const QMessageLogContext &, const QString &msg)
{
    std::cout << msg.toStdString().c_str();
}

std::streamsize myConsoleStream::xsputn(const char *p, std::streamsize n)
{
    QString str(p);
    if(str.contains("\n"))
    {
        QStringList strSplitted = str.split("\n");

        this->log_window->moveCursor (QTextCursor::End);
        this->log_window->insertPlainText (strSplitted.at(0)); //Index 0 immer noch auf der alten Zeile

        for(int i = 1; i < strSplitted.size(); i++)
        {
            this->log_window->append(strSplitted.at(i));
        }
    }
    else
    {
        log_window->moveCursor (QTextCursor::End);
        log_window->insertPlainText (str);
    }
    return n;
}

myConsoleStream.h:

#ifndef Q_DEBUGSTREAM_H
#define Q_DEBUGSTREAM_H

#include <iostream>
#include <streambuf>
#include <string>
#include <QObject>
#include <QWidget>
#include "QTextEdit"
#include <QApplication>
#include "myconsole.h"


class myConsoleStream :  public std::basic_streambuf<char>,  myConsole
{

public:
    myConsoleStream(std::ostream &stream, QTextEdit* text_edit, QWidget *parent);


    virtual ~myConsoleStream();
    static void registerMyConsoleMessageHandler();

private:

    static void myConsoleMessageHandler(QtMsgType, 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

I tried to make this class a subclass of an additional class to which I promoted the QTextEdit to.Which looks like this:

#include "myconsole.h"


myConsole::myConsole(QWidget *parent)
    :QTextEdit(parent)
{

}

myConsole::~myConsole()
{        
}

Last but not least my Mainwindow Class looks like this:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QBoxLayout>
#include <QTimer>
#include "myconsolestream.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    new myConsoleStream(std::cout, this->ui->Console,this);//Redirect Console output to QTextEdit
    myConsoleStream::registerMyConsoleMessageHandler(); //Redirect qDebug() output to QTextEdit


    std::cout << "Hallo" << std::endl;
}

MainWindow::~MainWindow()
{
    delete ui;


}

If I execute this there appears a second QTextEdit in the left upperhand corner of my Mainwindow, which I dont want to have there. And I cant figure out why this is appearing or where this is created?

Btw I am using qt5.5 and QtCreator for that matter.


Solution

  • It looks like you create your own QTextEdit with the myConsole class and you also redirect your output to this->ui->Console which I guess is created with the UI designer and also an instance of QTextEdit. myConsole in then displayed in the top left of your window because you don't provide it with any layout information and just a parent widget.

    To clarifiy, your myConsoleStream is derived from myConsole which in term is derived from QTextEdit, so your myConsoleStream is also an object of type QTextEdit itself.

    If you follow the example provided in your link you don't have to create another QTextEdit, if you want to do that you also have to place it in your UI etc..