我如何从 QProcess 中读取数据?

Posted

技术标签:

【中文标题】我如何从 QProcess 中读取数据?【英文标题】:How do I read from QProcess? 【发布时间】:2013-03-25 12:26:42 【问题描述】:

我有这个简单的 C++ 程序:

int main(int argc, char *argv[])


    QCoreApplication a(argc, argv);

    QProcess ps;
    QByteArray ba;

    ps.start("ls J:");
    ba = ps.readAllStandardOutput();
    char *someData = ba.data();

    cout << "Testing QProcess ..." << endl;
    cout << someData << endl;
    cout << "done!" << endl;

    return a.exec();

输出是:

Testing QProcess ...


done!

如果我从 Windows cmd 运行“ls J:”,它就可以工作。 我错过了什么?

【问题讨论】:

hmmm... M$ 实现了linux的ls ? @borisbn:因为我的系统中有 MSYS 可以正常工作。即使我更改为 Windows 例如"dir J:" 它不适用于我的程序,但它适用于 Windows cmd。 【参考方案1】:

在循环中使用QIODevice::waitForReadyRead(),只有在返回之后,才调用readAllStandardOutput()。正如文档中所说,QProcess::readAllStandardOutput() 将读取所有 可用 数据,但不会等待。在开始阅读之前,您需要等待该过程以QProcess::waitForStarted() 开始。

快速未经测试的部分代码,将ba = ps.readAllStandardOutput();行替换为:

if (ps.waitForStarted(-1)) 
    while(ps.waitForReadyRead(-1)) 
        ba += ps.readAllStandardOutput();
    

// else report error or whatever

当出现错误或子进程终止时应该退出循环,但继续阅读直到那时,没有超时。

注意:在“常规”Qt 程序中,您将运行事件循环,然后您不会调用waitForReadyRead() 或其他类似的便利函数。他们会阻止事件循环并停止其他一切。在这样的程序中,您最好使用信号和槽,或者开始使用线程(但这通常不是首选,它只会增加不必要的复杂性)。

【讨论】:

在循环中使用 QIODevice::waitForReadyRead() 是指事件循环还是 while/if-else 循环? 测试了你添加的那段代码,它给出了和以前一样的输出。 @Amani 你确定这个ls 打印到标准输出而不是标准错误吗?尝试使用setProcessChannelMode(QProcess::MergedChannels) 另外,循环中,在调用 read 方法之前尝试添加qDebug() &lt;&lt; ps.bytesAvailable(); 现在它可以与添加的代码一起使用,但是如果我将“ls J:”更改为“dir J:”,它会给我与以前相同的输出。【参考方案2】:

QProcess documentation 表示,当有数据可供读取时,QProcess 对象会发出信号:readyRead()readyReadStandardOutput()readyReadStandardError()

最简单的方法是将这些信号连接到您的插槽,然后使用例如。 readAllStandardOutput() 那里。

当然海德斯循环也可以。

【讨论】:

以上是关于我如何从 QProcess 中读取数据?的主要内容,如果未能解决你的问题,请参考以下文章

我怎么知道 QProcess 何时想要读取输入?

QProcess没有从命令中读取结果

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

如何读取 QProcess 输出

QProcess 无缘无故死亡

QT读取文本文件