c++ - 在 Qt 中读取连续 QProcess 的标准输出

标签 c++ qt console output qprocess

我在使用 Qt 的 QProcess 方面遇到了一些问题。我已将以下功能与按钮的 onClick 事件连接起来。基本上,我想在单击此按钮时执行另一个文件,并在我的 Qt 程序中获取它的输出。此文件 calculator 执行,显示一些输出,然后等待用户的输入。

void runPushButtonClicked() {
    QProcess myprocess;
    myprocess.start("./calculator")
    myprocess.waitForFinished();
    QString outputData= myprocess.readStandardOutput();
    qDebug() << outputData;
}

在一个场景中,当calculator 是一个只输出一些结果并最终终止的文件时,这很完美。但是,如果计算器在输出一些结果后等待用户的进一步输入,我的 outputData 中什么也得不到。事实上,waitForFinished() 会超时,但即使我删除了 waitForFinished()outputData 仍然是空的。

我已经在 SO 上尝试了一些可用的解决方案,但无法处理这种情况。任何指导将不胜感激。

最佳答案

我建议您设置一个信号处理程序,在子进程产生输出时调用它。例如。你必须连接到 readyReadStandardOutput .

然后您可以识别子流程何时需要输入并发送您想要的输入。这将在 readSubProcess() 中完成。

main.cpp

#include <QtCore>
#include "Foo.h"

int main(int argc, char **argv) {
   QCoreApplication app(argc, argv);

   Foo foo;

   qDebug() << "Starting main loop";
   app.exec();
}

接下来,启动子流程并检查输入。当 calculator 程序完成时,main 程序也退出。

Foo.h

#include <QtCore>

class Foo : public QObject {
   Q_OBJECT
   QProcess myprocess;
   QString output;

public:
   Foo() : QObject() {
      myprocess.start("./calculator");

      // probably nothing here yet
      qDebug() << "Output right after start:"
               << myprocess.readAllStandardOutput();

      // get informed when data is ready
      connect(&myprocess, SIGNAL(readyReadStandardOutput()),
              this, SLOT(readSubProcess()));
   };

private slots:
   // here we check what was received (called everytime new data is readable)
   void readSubProcess(void) {
      output.append(myprocess.readAllStandardOutput());
      qDebug() << "complete output: " << output;

      // check if input is expected
      if (output.endsWith("type\n")) {
         qDebug() << "ready to receive input";

         // write something to subprocess, if the user has provided input,
         // you need to (read it and) forward it here.
         myprocess.write("hallo back!\n");
         // reset outputbuffer
         output = "";
      }

      // subprocess indicates it finished
      if (output.endsWith("Bye!\n")) {
         // wait for subprocess and exit
         myprocess.waitForFinished();
         QCoreApplication::exit();
      }
   };
};

对于子进程计算器,使用了一个简单的脚本。您可以看到生成输出的位置以及需要输入的位置。

#/bin/bash

echo "Sub: Im calculator!"

# some processing here with occasionally feedback
sleep 3
echo "Sub: hallo"

sleep 1

echo "Sub: type"
# here the script blocks until some input with '\n' at the end comes via stdin
read BAR

# just echo what we got from input
echo "Sub: you typed: ${BAR}"

sleep 1
echo "Sub: Bye!"

如果您不需要在主进程中做任何其他事情(例如显示 GUI、管理其他线程/进程....),最简单的方法就是在 sleep 中子流程创建后的循环,然后是类似 readSubprocess 的内容。

关于c++ - 在 Qt 中读取连续 QProcess 的标准输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46432912/

相关文章:

c - 如何在控制台中运行c项目

C# 问题读取控制台输出到字符串

c++ - & 在类型后的函数参数中

c++ - 模板化类声明 C++

c++ - Qt 如何将项目添加到具有偏移量的场景中?

c++ - 派生 QMainWindow 并更改其布局

qt - 如何从 QProcess 获取 STDOUT?

ruby-on-rails - 控制台应用程序的 Boson vs Thor

c++ - 如何在 Windows 10 x64 下通过 Clion 2017.1 编译 32 位应用程序?

c++ - 布隆过滤器误报