简体   繁体   English

在Qt中读取连续QProcess的stdoutput

[英]Read stdoutput of continuous QProcess in Qt

I am having some problem regarding QProcess using Qt. 我对使用Qt的QProcess有一些问题。 I have connected the following function with the onClick event of a push button. 我已将以下功能与按钮的onClick事件连接。 Basically, I want to execute another file when this button is clicked, and get its output on my Qt program. 基本上,我想在单击此按钮时执行另一个文件,并在我的Qt程序中获取其输出。 This file calculator executes, displays some output, and then waits for an input from the user. 该文件calculator执行,显示一些输出,然后等待用户的输入。

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

In a scenario, when the calculator is such a file that only outputs some results and terminates eventually, this works perfect. 在一种情况下,当calculator是仅输出一些结果并最终终止的文件时,这是完美的。 But, in case when the calculator waits for some further input from the user after outputting some results, I get nothing in my outputData . 但是,如果计算器在输出一些结果后等待用户的进一步输入,则在outputData什么也没有。 In fact, waitForFinished() would time out, but even when I remove waitForFinished() , the outputData would still be empty. 实际上, waitForFinished()会超时,但是即使删除了waitForFinished()outputData仍然为空。

I have already tried some of the solutions available here on SO, but have been unable to handle this case. 我已经尝试过SO上可用的一些解决方案,但是无法处理这种情况。 Any guidance will be much appreciated. 任何指导将不胜感激。

I would suggest, that you setup a signal handler, that gets called when the subprocess produces output. 我建议您设置一个信号处理程序,该处理程序在子进程产生输出时被调用。 Eg you have to connect to readyReadStandardOutput . 例如,您必须连接到readyReadStandardOutput

Then you can identify, when subprocess demands input and send the input you want. 然后,您可以确定子流程何时需要输入并发送所需的输入。 This will be done in readSubProcess() . 这将在readSubProcess()

main.cpp 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();
}

In the following, the subprocess is started and the input checked. 接下来,将启动子流程并检查输入。 When the calculator program finishes, the main also exits. calculator程序完成后,主电源也会退出。

Foo.h oo

#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();
      }
   };
};

For the subprocess calculator a simple script is used. 对于子过程计算器,使用一个简单的脚本。 You can see the where output is generated and where input is expected. 您可以看到生成输出的位置和预期输入的位置。

#/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!"

If you do not need to do anything else in your main process (eg show a GUI, manage other threads/processes....), the easiest would be to just in a sleep in a loop after subprocess creation and then something like readSubprocess . 如果您不需要在主流程中执行其他任何操作(例如,显示GUI,管理其他线程/流程...。),最简单的方法就是在创建子流程后再进入循环sleep ,然后再执行诸如readSubprocess类的readSubprocess

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM