Qt C++ - 如何成功地将数据传递给子进程?

Posted

技术标签:

【中文标题】Qt C++ - 如何成功地将数据传递给子进程?【英文标题】:Qt C++ - How to successfully pass data to child process? 【发布时间】:2017-08-17 09:40:56 【问题描述】:

我编写了一个简短的测试软件,其目标是通过子进程实际启动我的 python 虚拟环境并在该进程中执行一些命令。似乎子进程永远不会收到数据。

下面的代码做了两件事:将数据,即字符串“John”传递给子进程,并在每次传递字符串时读取日志文件(检查例如命令是否被正确理解)。

在我的终端中输入以下内容(出于测试目的,我故意执行了错误的命令):

   $ script -f -c python2 python.log
   Script started, file is python.log
   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.
   >>> John
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   NameError: name 'John' is not defined

我的 python.log 文件现在包含(如预期和想要的那样):

   Script started on Don 17 Aug 2017 01:04:54 CEST
   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.
   >>> John
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   NameError: name 'John' is not defined
   >>> 

应该复制此行为的相应代码:

在我的 gui 上按下按钮时,此代码将被执行:

    void MainWindow::mainFunction()
   
       QFile myfile("/home/John/Desktop/python.log");
       QTextStream input(&myfile);
       if(!myfile.open(QIODevice::ReadOnly)) 
           QMessageBox::information(0, "error", myfile.errorString());
       

       QProcess p;    //childprocess
       QStringList params;
       qint64 successFailWrite;
       qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
       connect(&p, &QProcess::errorOccurred, qApp, &QApplication::aboutQt );
       //connect(&p, &QProcess::started, qApp, &QApplication::aboutQt);
       params<<"-f"<<"-c"<<"python2 python.log";
       qDebug()<<"parameters: "<<params;
       p.start("script", params);
       while(!p.waitForStarted())
       qDebug()<<"waiting for started";


       while(1)
       
           successFailWrite = p.write("John", 1);

           while(!input.atEnd())
           
               QString line = input.readLine();
               qDebug()<<"read: "<<line;
           
       
   

执行此代码时,我的 python.log 文件始终为空,但 successFailWrite 变量为 1,这意味着它成功地将字符串写入进程。同样奇怪的是,当我替换时

       p.start("script", params); 

with: p.start("scriptttt", params);

什么都没有改变,aboutQt SLOT 没有被激活,我在任何地方都看不到任何错误消息。 According to the Qt documents I should be able to interface with my process using write() just like an IODevice

我做错了什么?

编辑: 参数

但是,我可以看到在执行我的代码时会发生这种情况:

$ ps aux | grep python

John+  7436  0.0  0.0  22352  2716 ?        S    11:56   0:00 script -f -c python2 python.log
John+  7437  0.5  0.1  31648  6924 pts/20   Ss+  11:56   0:00 python2
John+  7439  0.0  0.0  14540  1020 pts/0    S+   11:56   0:00 grep --color=auto python

【问题讨论】:

你觉得p.write("John", 1)实际上是does怎么样? @G.M.将字符串写入进程。请注意,我阅读了文档......但仍然有问题。我可以使用$ps aux 看到该进程正在启动,但看起来该进程没有收到我的数据,因为我的文件始终为空。但另一方面,该函数返回 1,这意味着它成功地将字符串写入进程。所以有些地方出了问题。 请再次查看docs。第二个参数是要写入的最大字节数。此外,您可能需要在解释器接受输入之前编写一个换行符。 @G.M.我担心还是有问题:successFailWrite = p.write("John\n", 30);。这也没有用。 【参考方案1】:

您的代码有几个问题。首先,正如cmets中所指出的,下面的代码...

p.write("John", 1);

只会写一个字符。由于您有一个以空结尾的字符串,只需使用接受该字符串的QIODevice::write 重载并记住包含换行符...

p.write("John\n");

更重要的是,你有...

params << "-f" << "-c" << "python2 python.log";

您需要拆分“python2 python.log”——这是两个单独的参数。试试……

params << "-f" << "-c" << "python2" << "python.log";

通过上述更改,代码对我来说可以正常工作。

【讨论】:

好吧,我的错你是对的。当我在桌面上查看同名的旧文件时,它实际上创建了一个位于“exe”位置的文件。正在写入的文件与我从中读取的文件不同。接受你的回答,谢谢。 你的事件循环在哪里?没有它,什么都不会发生。 事件循环到底是为了什么?目前它读取和写入。什么意思? 它可以正确写入和读取,因为我添加了延迟,但我明白你的意思。

以上是关于Qt C++ - 如何成功地将数据传递给子进程?的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据传递给子 UINavigationController?

在准备 segue 时,如何将数据传递给子 UIViewController?

Android:如何将数据传递给子活动?

如何将数据传递给 vue.js 中的子组件

SwiftUI 将数据传递给子视图

如何将数据传递给嵌套的子组件vue js?