简体   繁体   English

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

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

Platform:Windows10 I use QProcess::start execute the Python file(in same diretory),but i can't get results from readAllStandardOutput function.平台:Windows10 我使用QProcess::start执行 Python 文件(在同一目录中),但我无法从readAllStandardOutput函数中获得结果。

Python file code : Python文件代码:

test.py测试文件

print “hello,world”

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

I can get output when I execute test.py , but when I use readAllStandardOutput I can't get it.当我执行test.py时我可以获得输出,但是当我使用readAllStandardOutput我无法获得它。 It a just print "" without data.它只是打印“”而没有数据。

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

In fun2 function, the function execute() can print "hello,world" at Qt terminal, but I can't get the standard output with readAllStandardOutput function.fun2函数中,函数execute()可以在 Qt 终端print "hello,world" ,但是我无法使用readAllStandardOutput函数获取标准输出。 The a also print "" without data i don't know why?一个也打印“”没有数据我不知道为什么?

Because I want to use the python module "requests" to visit a url directly, so I want my C++ code can execute this python file.因为我想使用python模块“requests”直接访问一个url,所以我希望我的C++代码可以执行这个python文件。 So, if you have a better way, tell me please.所以,如果你有更好的方法,请告诉我。

When QProcess::start() is used, the process is started in another thread and it is executed asynchronously, to avoid blocking the GUI thread of your application (if you have a GUI).当使用QProcess::start() ,进程在另一个线程中启动并异步执行,以避免阻塞应用程序的 GUI 线程(如果您有 GUI)。 Using the waitForReadyRead() will block the execution of your application as well, till the process ends.使用waitForReadyRead()也会阻止应用程序的执行,直到进程结束。

You may consider using Qt's signal/slot system to catch the output of your process when available, without blocking the main thread.您可以考虑使用 Qt 的信号/槽系统在可用时捕获进程的输出,而不会阻塞主线程。

This version of fun1() requires C++11:这个版本的 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");
}

In this way you could also manage execution errors, or at least make the user aware of it.通过这种方式,您还可以管理执行错误,或者至少让用户意识到这一点。

Getting process output is a bit cumbersome in Qt, unfortunately.不幸的是,在 Qt 中获取进程输出有点麻烦。

Here's how I do it in one project:以下是我在一个项目中的做法:

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

This probably raises a few questions:这大概会引发几个问题:

setProcessChannelMode(QProcess::MergedChannels) will merge the output channels. setProcessChannelMode(QProcess::MergedChannels)将合并输出通道。 Various programs write to different outputs.各种程序写入不同的输出。 Some use the error output for their normal logging, some use the "standard" output, some both.有些使用错误输出进行正常记录,有些使用“标准”输出,有些两者兼而有之。 Better to merge them.最好将它们合并。

readAll() reads everything available so far. readAll()读取目前可用的所有内容。

It is put in a loop with waitForReadyRead(-1) (-1 means no timeout), which will block until something is available to read.它被放入一个带有waitForReadyRead(-1)的循环中(-1 表示没有超时),它会阻塞直到可以读取某些内容。 This is to make sure that everything is actually read.这是为了确保实际读取所有内容。
Simply calling readAll() after the process is finished has turned out to be highly unreliable (buffer might already be empty).在进程完成后简单地调用 readAll() 被证明是非常不可靠的(缓冲区可能已经是空的)。

use waitForReadyRead() Process API to read data.使用 waitForReadyRead() 进程 API 读取数据。 waitForReadyRead() blocks until new data is available for reading on the current read channel. waitForReadyRead() 阻塞,直到新数据可用于在当前读取通道上读取。

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


    qDebug()<<a;
}

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

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