将std :: cout重定向到QTextEdit

时间:2012-02-09 13:00:01

标签: c++ qt iostream

是否有可能(更重要的是-how-)将输出流重定向到QTextBox。那么如果我在应用程序的任何地方写std::cout << "test",它会被重定向到我定义的文本框?

我试过了明显的(其中ui.textEdit是指向文本编辑框的指针):

std::cout.rdbuf(ui.textEdit);
std::cout << "test";

然而,这不起作用。 (明显)。 - 也没有将cout重定向到qDebug工作(甚至将qDebug指向文本字段)。

我正在使用qt4.8 btw ...

编辑: 所以我尝试了邮件列表中发布的解决方案。但是现在出现了访问冲突。

class MainInterface : public QMainWindow
{
    Q_OBJECT
....
private: 
    QDebugStream qout

使用构造函数:

MainInterface::MainInterface(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags),
    qout(std::cout, ui.textEdit)
{

在成员函数中,发布了以下行:std::cout << "Project Loaded" << std::endl;

该行现在导致来自“qscoped_pointer”的访问冲突。 (作为单独的问题,我应该发布更详细的信息吗?)

编辑:“解决方案”是在完全创建ui.textEdit之后才声明qout。

2 个答案:

答案 0 :(得分:1)

您可以将cout重置为您自己的ostream实施,这将emit信号通知您挂钩到append广告位。因此,你的子问题/练习是:

  1. 重定向cout
  2. cout重定向到您自己的ostream实施或您可以扩展的实施
  3. emitQTextBox
  4. 发出信号

    据我所知,这些子主题在SO上可用

答案 1 :(得分:1)

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.