平台:Windows10
我使用QProcess::start
执行Python文件(在同一个目录中),但是我
无法从readAllStandardOutput
函数获得结果。
test.py
print “hello,world”
#include <QProcess>
#include <QStringList>
#include <QByteArray>
#include <QDebug>
void fun1(){
QProcess process;
process.start("python test.py");
process.waitForFinished();
QByteArray a = process.readAllStandardOutput();
qDebug()<<a;
}
int main(){
fun1();
}
当我执行 test.py 时,我可以获得输出,但是当我使用readAllStandardOutput
时,我无法获得它。它只是一个印刷&#34;&#34;没有数据。
#include <QProcess>
#include <QStringList>
#include <QByteArray>
#include <iostream>
#include <QDebug>
void fun2(){
QStringList args("F:/test.py");
QProcess process;
process.execute(QString("Python.exe"), args);
QByteArray a = process.readAllStandardOutput();
process.waitForFinished();
qDebug()<<a;
}
int main(){
fun1();
qDebug<<"--------";
fun2();
}
在fun2
函数中,函数execute()
可以在Qt终端print "hello,world"
,但我无法通过readAllStandardOutput
函数获得标准输出。 a也打印&#34;&#34;没有数据我不知道为什么?
因为我想使用python模块&#34;请求&#34;直接访问url,所以我希望我的C ++代码可以执行这个python文件。所以,如果你有更好的方法,请告诉我。
答案 0 :(得分:0)
不幸的是,在Qt中获取流程输出有点麻烦。
以下是我在一个项目中的表现:
QProcess process;
process.setProcessChannelMode(QProcess::MergedChannels);
process.start(processToStart, arguments)
// Get the output
QString output;
if (process.waitForStarted(-1)) {
while(process.waitForReadyRead(-1)) {
output += process.readAll();
}
}
process.waitForFinished();
这可能会引发一些问题:
setProcessChannelMode(QProcess :: MergedChannels)将合并输出通道。各种程序写入不同的输出。有些人使用错误输出进行正常记录,有些人使用&#34;标准&#34;输出,一些两者。最好合并它们。
readAll()读取到目前为止可用的所有内容。
它被放入一个带有 waitForReadyRead(-1)的循环中(-1表示没有超时),它将阻塞,直到有东西可供读取。这是为了确保所有内容都被实际阅读 在进程完成后简单地调用readAll()已证明是非常不可靠的(缓冲区可能已经为空)。
答案 1 :(得分:0)
使用waitForReadyRead()Process API读取数据。 waitForReadyRead()将阻塞,直到新数据可用于在当前读取通道上读取。
void fun1(){
QProcess process;
process.start("python test.py");
process.waitForReadyRead();
QByteArray a = process.readAllStandardOutput();
qDebug()<<a;
}
答案 2 :(得分:0)
当使用QProcess::start()
时,进程在另一个线程中启动,并以异步方式执行,以避免阻塞应用程序的GUI线程(如果您有GUI)。使用waitForReadyRead()
也会阻止应用程序的执行,直到流程结束。
您可以考虑使用Qt的信号/插槽系统在可用时捕获进程的输出,而不会阻塞主线程。
此版本的fun1()需要C ++ 11:
void fun1(){
// instantiate dynamically to avoid stack unwinding before the process terminates
QProcess* process = new QProcess();
process->start("python test.py");
// catch data output
QObject::connect(process, &QProcess::readyRead, [process] () {
QByteArray a = process->readAll();
qDebug() << a;
});
// delete process instance when done, and get the exit status to handle errors.
QObject::connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
[=](int exitCode, QProcess::ExitStatus /*exitStatus*/){
qDebug()<< "process exited with code " << exitCode;
process->deleteLater();
});
}
通过这种方式,您还可以管理执行错误,或者至少让用户知道它。