在Qt中获取输出:'QProcess::start()'和'QProcess:readAllStandardOutPut()'

Get Output in Qt: 'QProcess::start()' and 'QProcess:readAllStandardOutPut()'

本文关键字:QProcess 获取 readAllStandardOutPut start Qt 输出      更新时间:2023-10-16

平台:Windows10我使用 QProcess::start执行python文件(以同一diretory(,但是我 无法从readAllStandardOutput函数获得结果。

Python文件代码:

test.py

print “hello,world”

QT:

#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时,我无法获得它。它只是一个无数据打印的"。

#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还打印"没有数据,我不知道为什么?

因为我想使用Python模块"请求"直接访问URL,因此我希望我的C 代码可以执行此Python文件。因此,如果您有更好的方法,请告诉我。

当使用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(); 
    // 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();
    });
    // start the process after making signal/slots connections 
    process->start("python test.py");
}

通过这种方式,您还可以管理执行错误,或者至少使用户意识到它。

获取过程输出在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(将合并输出通道。各种程序写入不同的输出。有些人将错误输出用于正常日志记录,有些使用"标准"输出,有些则使用。最好合并它们。

readall((读取到目前为止可用的所有内容。

将其放在 waitforreadyread(-1((-1表示无时间表(的循环中,这将阻止,直到可以阅读的东西。这是为了确保一切实际读取。
简单地调用readall((完成后,事实证明是高度不可靠的(缓冲区可能已经为空(。

使用waitforreadyread((进程API读取数据。waitforreadyread((块,直到可以在当前读取通道上读取新数据。

void fun1(){
    QProcess process;
    process.start("python test.py");
    process.waitForReadyRead();
    QByteArray a = process.readAllStandardOutput();

    qDebug()<<a;
}