redirect std::cout to QTextEdit

前端 未结 2 1175
日久生厌
日久生厌 2021-01-19 23:49

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 applicati

2条回答
  •  梦毁少年i
    2021-01-20 00:06

    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
    {
    
    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()
        ,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.

提交回复
热议问题