首页 文章

在Qt中读取连续QProcess的stdoutput

提问于
浏览
1

关于使用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上尝试了一些可用的解决方案,但是无法处理这种情况 . 任何指导将不胜感激 .

1 回答

  • 0

    我建议你设置一个信号处理程序,当子进程产生输出时调用它 . 例如 . 你必须连接到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 程序完成后,主程序也会退出 .

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

    对于子进程 calculator ,使用了一个简单的脚本 . 您可以看到生成输出的位置以及预期输入的位置 .

    #/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 .

相关问题