Qt - 如何将“更多”数据写入 QProcess?

Posted

技术标签:

【中文标题】Qt - 如何将“更多”数据写入 QProcess?【英文标题】:Qt - How to write "more" data to QProcess? 【发布时间】:2017-08-27 19:16:59 【问题描述】:

到目前为止,我遇到了几次遇到的问题。 有问题的问题每次都会自行解决,而我不明白是什么原因造成的 所以发生的事情是我从我的 c++ 代码启动了一个 python 虚拟环境。这很有效,之后通过使用 write 功能,我可以在那个环境中写东西。到目前为止,这也非常有效。但是我无法将我的最后一个命令写入该进程。 我虽然可能有些缓冲区已满,但我在 Qt 文档中并没有真正找到有关缓冲区的任何信息

这是相关的代码:

static QStringList params;
QProcess *p = new QProcess();

params<<"-f"<<"-c"<<"python2"<< "/home/John/Desktop/python.log";
qDebug()<<"parameters: "<<params;

qDebug()<<"going to write";
p->start("script", params);
qDebug()<<"Turning on new user process...";
while(!p->waitForStarted())
qDebug()<<"waiting for virtualenv to be ready";
successFailWrite = p->write("import imp;\n");
while(!p->waitForBytesWritten());
successFailWrite = p->write("foo = imp.load_source('myTest', '/home/John/recognitionClass.py');\n");
while(!p->waitForBytesWritten());
successFailWrite = p->write("from myTest import recognitionClass;\n");
while(!p->waitForBytesWritten());
successFailWrite = p->write("myClassObj = recognitionClass();\n");
if(successFailWrite !=-1)
qDebug()<<"OK written";
while(!p->waitForBytesWritten());
successFailWrite = p->write("habelahabela\n");
if(successFailWrite !=-1)
qDebug()<<"OK written";

QString name = "John";
QString processNewUserParameter= "print myClassObj.addNewUser("+ name +");\n";
QByteArray processNewUserParameterByteArr= processNewUserParameter.toUtf8();
p->write(processNewUserParameterByteArr);

我保留了一个日志文件,其中包含正在写入 python virtualenv 的内容以及正在打印的内容

Script started on Son 27 Aug 2017 20:09:52 CEST
import imp;
foo = imp.load_source('myTest', '/home/John/recognitionClass.py');
from myTest import recognitionClass;
myClassObj = recognitionClass();
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import imp;
>>> foo = imp.load_source('myTest', '/home/John/recognit
<myTest', '/home/John/recogniti                         onClass.py');
/usr/local/lib/python2.7/dist-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
  "This module will be removed in 0.20.", DeprecationWarning)
/usr/local/lib/python2.7/dist-packages/sklearn/grid_search.py:43: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. This module will be removed in 0.20.
  DeprecationWarning)
>>> from myTest import recognitionClass;
>>> myClassObj = recognitionClass();
>>>

它确实提示“OKwritten”两次,这一方面证明我成功地将我的命令写入进程,但我什么都看不到。

正如您所见,测试句子“habelahabela”也没有写出来。 有人知道我可能做错了什么吗? 我知道我正在将命令快速写入环境。因为正如你所看到的,我从写“import imp”开始,然后它被缓冲,稍后缓冲区被刷新,virtualenv 执行命令(这就是你看到它两次的原因)。

有人知道为什么我看不到测试句,更重要的是我的实际命令"print myClassObj.addNewUser("+ name +");\n" 被打印到虚拟环境吗?

谢谢

【问题讨论】:

那个缓冲区是一些pipe(7)。你可能想处理readyRead & readyReadStandardOutput Qt 信号 @BasileStarynkevitch 好的谢谢你的澄清,你对我的问题有什么建议? 花几个小时阅读文档。还可以阅读一本关于Operating Systems的教科书 【参考方案1】:

首先,写while(!p-&gt;waitForBytesWritten());是没有意义的。 waitForBytesWritten 已经在没有 while 循环的情况下阻塞了您的线程,并且正如名称所述,一直等到写入字节。仅当存在超时或错误时,它才会返回 false。在第一种情况下,您应该给它更多时间来写入字节。在第二种情况下,您应该修复错误,然后再试一次。 waitForStarted 和所有其他以“waitFor...”开头的 Qt 函数也是如此。

所以用法如下:

if(!p->waitForBytesWritten(-1)) // waits forever until bytes ARE written

   qDebug() << "Error while writing bytes";

关于问题:我认为问题(或至少部分问题)是您将最后两条消息写入p,但您既没有等待bytesWritten() 信号,也不要使用waitForBytesWritten() 阻塞功能。虽然,可能没有发生错误(因为p-&gt;write(...) 那时没有返回-1),但这并不意味着你的消息已经写好了。简而言之,等待bytesWritten() 信号...

QProcess 继承自 QIODevice,所以我建议查看 its docs 并了解更多信息。

【讨论】:

以上是关于Qt - 如何将“更多”数据写入 QProcess?的主要内容,如果未能解决你的问题,请参考以下文章

在 Qt 控制台应用程序中读写 QProcess

QT读取文本文件

Qt4、QProcess、R:标准输出中的垃圾,行较长

Qt通过QProcess启动进程并传递命令行参数

Qt通过QProcess启动进程并传递命令行参数

Qt,ProcessState 枚举如何工作