我如何从 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() << ps.bytesAvailable();
。
现在它可以与添加的代码一起使用,但是如果我将“ls J:”更改为“dir J:”,它会给我与以前相同的输出。【参考方案2】:
QProcess
documentation 表示,当有数据可供读取时,QProcess
对象会发出信号:readyRead()
和 readyReadStandardOutput()
和 readyReadStandardError()
。
最简单的方法是将这些信号连接到您的插槽,然后使用例如。 readAllStandardOutput()
那里。
当然海德斯循环也可以。
【讨论】:
以上是关于我如何从 QProcess 中读取数据?的主要内容,如果未能解决你的问题,请参考以下文章