【问题标题】:How do I read from QProcess?我如何从 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。

标签: c++ qt qprocess


【解决方案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() 那里。

当然海德斯循环也可以。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多