将std::cout重定向到QTextEdit

5

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

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

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

然而,这样做不起作用(显然)。- 重定向cout到qDebug也不起作用(甚至将qDebug定向到文本字段也不行)。
顺便说一下,我正在使用qt4.8...
编辑: 因此,我尝试了邮件列表中发布的解决方案。但现在出现了访问冲突。
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个回答

2

我为这个问题编写了自己的函数,针对QTextEdit,只需注意如果在主线程上运行重操作,您的GUI将会冻结。因此,您需要实例化一个新的QThread,例如,然后GUI或者QTextEdit将相应地更新:

头文件:

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文件:

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;

       }
}

在您的主窗口中,您只需实例化您的新流:
new myConsoleStream(std::cout, this->ui->Console);
  myConsoleStream::registerMyConsoleMessageHandler(); 

你已经准备就绪了!希望这有所帮助。


1
你的回答中缺少xsputn函数。在这篇文章中可以找到一个非常类似的工作示例:https://stackoverflow.com/questions/46927087/redirecting-stdcout-from-dll-in-a-separate-thread-to-qtextedit - Kafka

1
您可以将 cout 重置为您自己的 ostream 实现,该实现将 emit 信号,您可以将其挂接到 append 插槽上。 因此,您需要解决以下子问题/练习:
  1. 重定向 cout
  2. cout 重定向到您自己的 ostream 实现或可扩展的实现
  3. emit 信号到 QTextBox

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接