监控正在运行的 qprocess 并在 qprocess 完成时返回值

Posted

技术标签:

【中文标题】监控正在运行的 qprocess 并在 qprocess 完成时返回值【英文标题】:Monitor running qprocess and return value when qprocess is finished 【发布时间】:2016-10-25 21:10:03 【问题描述】:

我想运行一个 qprocess(程序 adb),并在进程完成后将结果返回给调用函数。但是,adb 很可能会发现自己处于循环中,将诸如“ADB 服务器未确认”之类的错误消息打印到标准输出,但从未完成。我需要捕获这些错误。

   QProcess run_command;
   connect(&run_command,SIGNAL(readyReadStandardOutput()),this,SLOT( dolog() ));       
   QString result=RunProcess("adb connect 192.168.1.100");

    ...

   QString MainWindow::RunProcess(QString cstring)
     

    run_command.start(cstring);

      // keep gui active for lengthy processes.                      

       while(run_command.state() != QProcess::NotRunning)  
          qApp->processEvents();

      QString command=run_command.readAll();
      return command;  // returns nothing if slot is enabled.
    

    void MainWindow::dolog()
         
            QString logstring = run_command.readAllStandardOutput();
              if (logstring.contains("error condition")
                 logfile("Logfile:"+logstring);

         

如果我启用信号/插槽,dolog() 将 stdout 打印到日志文件,但 RunProcess 返回一个空白字符串。如果我禁用信号/插槽,RunProcess() 会按预期返回 qprocess 输出。

【问题讨论】:

忘记processEvents() 的存在。 99% 的时间都用错了,这里就是这种情况。你可以编写非常好的应用程序,数十万行,甚至一次都不调用它。如果你想运行一个进程并得到它的输出,你应该给进程的相关信号附加一个或多个槽。你也不想使用readAllStandardOutput,而是通过while (run_command.canReadLine()) auto line = run_command.readLine(); ... 单独处理每一行 【参考方案1】:

首先,您需要确定有问题的命令正在使用哪个输出流来处理其错误。 它与stderr 非常相似,因此您需要连接到readyReadStandardError() 信号。

对于命令本身,我建议将其拆分为命令和参数,并使用带有命令和参数列表的QProcess::start() 重载。 比依赖单个字符串再次正确分隔更强大。

【讨论】:

以上是关于监控正在运行的 qprocess 并在 qprocess 完成时返回值的主要内容,如果未能解决你的问题,请参考以下文章

QProcess 附加到从脚本运行的可执行文件

在 Qt QProcess 中运行 sudo 命令

等待 QProcess 完成或持续时间超过 [重复]

使用 qprocess 运行 .exe

从 QThread 启动 QProcess [重复]

使用 QProcess 获取所有正在运行的进程信息