【问题标题】:redirect std::cout to QTextEdit将 std::cout 重定向到 QTextEdit
【发布时间】:2012-02-09 13:00:01
【问题描述】:

是否有可能(更重要的是 -how-)将输出流重定向到 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 &lt;&lt; "Project Loaded" &lt;&lt; std::endl;

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

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

【问题讨论】:

    标签: c++ qt iostream


    【解决方案1】:

    您可以将cout 重置为您自己的ostream 实现,这将emit 信号您挂接到append 插槽。因此,您的子问题/练习是:

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

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

    【讨论】:

      【解决方案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;
      
             }
      }
      

      在您的主窗口中,您只需实例化您的新 Stream :

      new myConsoleStream(std::cout, this->ui->Console);
        myConsoleStream::registerMyConsoleMessageHandler(); 
      

      你也很好! 希望这会有所帮助。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2012-06-16
      • 2010-10-06
      相关资源
      最近更新 更多