使用 QProcess 读取标准输出

Posted

技术标签:

【中文标题】使用 QProcess 读取标准输出【英文标题】:Using QProcess to read standard output 【发布时间】:2018-03-01 20:20:08 【问题描述】:

在我的 QT 小部件应用程序中,我试图运行一个 shellscript,它打开一个 C++ 程序并为程序提供输入。该程序启动一个命令提示符,需要用户输入才能启动。一旦程序启动,程序的输出将通过标准输出重定向到文本文件。我正在尝试使用 QProcess 打开并运行这个 shellscript,然后读取用于将 C++ 程序的结果打印到文本文件的标准输出。 shell 脚本只运行这个进程并且不会终止它。这是因为我需要在程序运行时不断地将此输出读入 GUI。等到程序完成读取这些信息是不够的。我对 QT 和 C++ 编程相当陌生。我希望有人可以帮助我实现这一点。

QProcess process;
process.start("/home/pi/Desktop/ShellScripts/RunTutorial3.sh");
QString output =process.readAllStandardOutput();
qDebug() << output;
QString err = process.readAllStandardError();
qDebug() << err;

我尝试过使用其他读取功能,例如 readline,并尝试将进程作为分离进程启动。我的任何实验都没有成功。是否有可能做我在 QT 中尝试的事情。我只需要程序连续运行并让 QT 经常读取此输出。

Shell 脚本:

#!/bin/bash
cd
cd Desktop
cd tutorial3App
cd bin
echo "start" | ./tutorial3 

C++ 代码:我需要在标准输出中捕获 meanTOE 值以在我的 GUI 中使用。

/ Calculate average time to end of discharge
            double meanToE = std::accumulate(ToESamples.begin(), ToESamples.end(), 0.0)/ToESamples.size();
            file << ": EOL in " << meanToE << " s" << std::endl;

【问题讨论】:

为什么要用bash运行tutorial3,而不是直接用QProcess运行呢?当您通过 bash 执行时,教程过程与 bash 是分开的。 我认为我的问题是 Qprocess 启动了脚本,但我不想为其提供结束论点。当脚本运行时,它不会让我在运行时连续读取它。我尝试使用 qprocess 打开它,但认为先使用 shell 脚本会更容易。 反而比较难,你的代码有几个问题,第一个可能是process是一个局部变量,在2打印空的东西后被删除,另一个问题是教程中的process3是与 bash 分离,因此您永远无法获得打印教程 3 的输出。如果你直接运行tutorial3,它更易于管理,因为Qt知道pid并且可以得到输出 我目前正致力于通过 QT 直接运行它。感谢您向我解释这个问题。起初我只是不确定 QProcess,因为它的文档没有提供很多示例,而且我对 c++ 编程的了解也不是很广泛。所以理解如何实现它被证明是困难的 我建议您查看我的示例代码,如果您有问题,请在 .pro 中使用 CONFIG += c++11 【参考方案1】:

正如我在 cmets 中所说的,主要问题之一是当您运行 tutorial3 时,该进程是分离的,因此您无法获得输出。所以我推荐直接执行,QProcess大概是一个局部变量,打印空文本后消除,一个可能的解决方案是创建一个指针。另一个改进是使用 readyReadStandardOutput 和 readyReadStandardError 信号,因为展示不是自动的。

QProcess *process = new QProcess(this);

connect(process, &QProcess::readyReadStandardOutput, [process, this]()
    QString output =process->readAllStandardOutput();
    qDebug() << "output: "<< output;
);

connect(process, &QProcess::readyReadStandardError, [process]()
    QString err = process->readAllStandardError();
    qDebug() << "error: "<<err;
);

process->setWorkingDirectory("/home/pi/Desktop/tutorial3App/bin/")
process->start("tutorial3", QStringList() << "start");

【讨论】:

这似乎甚至没有打开程序,但我会尝试关闭它。谢谢 @GageHaas 你会得到什么输出? 它在下一行输出一个 0 和一个 1 @GageHaas 我可以提供你的代码的minimal reproducible example,它对我很有用 @GageHaas 您必须使用插槽,这是主要部分。程序会编译你吗?您可以展示有关如何实施我的解决方案的更多信息。【参考方案2】:

我认为您必须阅读有关 Qt 中的信号和插槽的信息。 QProcess 有一个信号 readyReadStandardOutput。所以你必须连接到这个信号并且在你的插槽中你应该使用 QProcess 函数 readAllStandardOutput。换句话说,当你的 shell 程序输出一些东西时,你会在你的插槽中捕获它并转储它或任何你想要的东西。

检查这个问题的答案。它可能会对你有所帮助。

reading and writing to QProcess in Qt Console Application

【讨论】:

以上是关于使用 QProcess 读取标准输出的主要内容,如果未能解决你的问题,请参考以下文章

试图从生成的 QProcess 中读取标准输出

如何读取 QProcess 输出

QT软件开发: QProcess启动进程完成交互并获取输出

QProcess 从标准输入和标准输出的文件开始

Qt QProcess::finished() 信号没有这样的插槽

Qt4、QProcess、R:标准输出中的垃圾,行较长