PyQt4 QProcess.startDetached() - 无法获取生成进程的返回值和PID

时间:2015-07-20 14:32:29

标签: python qt pyqt4 qprocess

这是前一个问题的后续问题(我再次发布):PyQt4 QProcess state always 0, various slots not working too

代码(已修改):

主要应用:qprocess_test.py

#!/usr/bin/python

import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QProcess


class Example(QtGui.QWidget):


    def __init__(self):
        super(Example, self).__init__()
        self.command = "./testCommand.py"
        self.args = [""]
        self.initUI()

    def initUI(self):               
        hbox = QtGui.QHBoxLayout()
        hbox.addStretch(1)

        qbtn = QtGui.QPushButton('Start', self)
        qbtn.clicked.connect(self.toggleProcess)
        qbtn.resize(qbtn.sizeHint())
        hbox.addWidget(qbtn)

        # This button is for testing the responsiveness of the GUI after the QProcess has been started
        qbtn2 = QtGui.QPushButton('Click me', self)
        qbtn2.setCheckable(True)
        qbtn2.toggled.connect(self.toggleButton)
        qbtn2.resize(qbtn2.sizeHint())
        hbox.addWidget(qbtn2)

        self.setLayout(hbox)
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('QProcess controlled by a button')    
        self.show()

    def toggleProcess(self):
        res, pid = QProcess.startDetached(self.command, self.args)
            print "Starting process\n", str(res), " | pid = ", str(pid)

    def toggleButton(self, value):
        if value == True:
            print "Lalalala!"
        else:
            print "Didadida!"

def main(): 
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

现在所有 Start 按钮都会启动分离进程。我们的想法是,只要用户根据PID与之交互,就可以切换并停止/启动分离过程。

用于创建过程的应用程序:testCommand.py

#!/usr/bin/env python

while True:
    print "a"

在做了一些阅读和谷歌搜索后,我发现startDetached()函数在Python中返回2个值(在C ++中它是一个布尔函数,但它也设置了其中一个参数的值 - 指针 pid ):

  • bool:告诉我们分离过程的启动是否成功
  • int:如果操作成功,则给出已启动流程的PID

以下是我用于此信息的来源:

出于某种原因,这根本不起作用。以下是我测试过的两种情况:

  • 尝试从函数中获取bool和int值:

    res, pid = self.myProcess.startDetached(self.command, self.args)
    

    我收到此错误:

    Traceback (most recent call last):
      File "./qprocess_test.py", line 48, in toggleProcess
        res, pid = self.myProcess.startDetached(self.command, self.args)
    TypeError: 'bool' object is not iterable
    

    这告诉我,我无法迭代 startDetached()的返回值,因此实际只返回一个SINGLE值而不是两个,因为我在多段代码中再次看到了PyQt4文档......

  • 检查 startDetached()实际返回的内容:它似乎只返回一个int,我认为是PID。但是,如果它是PID,则它不是正确的值(查看 htop 的输出):

    val = QProcess.startDetached(self.command, self.args)
    # val = 0 (always!)
    

我已经知道 startDetached()是一个静态函数,因此任何未来与创建过程的交互都可以通过它的pid来完成,但是调用它的状态(QProcess.state())等等。因为没有对象可以与之交互,所以是不可能的。这个(破碎的)现在的工作方式确实是一个独立的过程,但由于我没有任何识别它的PID,我唯一的交互方式是手动查找 testCommand.py <的PID / strong>然后通过 kill 执行相应的信号。

有谁知道我在这里做错了什么?我可以了解基础并开始使用C / C ++进行各种系统调用,但我真的想学习如何使用PyQt4和Python来实现这一点。

谢谢!

修改

似乎startDetached()确实返回True | False。但无法找到PID ......不是官方文档中的内容。

1 个答案:

答案 0 :(得分:3)

函数startDetached在C ++中重载,它有几个签名。根据提供的参数,它不一定会返回相同的东西。

即使overloading does not exist in Python,你也有类似的东西:

import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QProcess

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)

    command = "./testCommand.py"
    args = [""]

    #"regular" startDetached : give two arguments, get a boolean
    process=QProcess()
    re=process.startDetached("ls",["."])
    print(re)
    print(type(re))

    #"overload" startDetached : give three arguments, get a tuple(boolean,PID)
    process2=QProcess()
    re,pid=process2.startDetached("ls",["."],".")
    print(re,pid)
    print(type(re),type(pid))