问题
This is a follow-up question to a previous one (again posted by me): PyQt4 QProcess state always 0, various slots not working too
The code (modified):
Main application: 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()
For now all the Start button does is start the detached process. The idea is for it to be toggable and stop/start the detached process whenever the users interacts with it based on the PID.
The application used for the created process: testCommand.py
#!/usr/bin/env python
while True:
print "a"
After doing some reading and googling I found out that the startDetached() function returns 2 values in Python (in the C++ it's a boolean function, but it also sets the value of one of its arguments - the pointer pid):
- bool: tells us if the starting of the detached process was successful or not
- int: gives the PID of the started process if the operation was successful
Here are the sources I have used for this information:
- http://doc.qt.io/qt-4.8/qprocess.html#startDetached
- http://pyqt.sourceforge.net/Docs/PyQt4/qprocess.html (due to current failure to load sourceforge properly here is the cached version: http://webcache.googleusercontent.com/search?q=cache:lQ-ixJIbVQQJ:pyqt.sourceforge.net/Docs/PyQt4/qprocess.html+&cd=1&hl=en&ct=clnk&gl=de&client=ubuntu)
For some reason this is not working at all. Here are the two situations that I have tested:
Trying to get both the bool and int values from the function:
res, pid = self.myProcess.startDetached(self.command, self.args)
I get this error:
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
This tells me that I can't iterate over the return value of startDetached() hence only a SINGLE value is actually returned and not two as I have also seen in multiple pieces of code again part of the PyQt4 documentation...
Checking what startDetached() actually returns: it seems it only returns an int, which I presume is the PID. However if it's the PID it is not the correct value (looking at the output of htop):
val = QProcess.startDetached(self.command, self.args) # val = 0 (always!)
I have learned that startDetached() is a static function hence any future interaction with the created process can be done via it's pid but things like calling its state (QProcess.state()) etc. are not possible since there is no object to interact with. The way this (broken) thing works right now is indeed start a detached process but since I don't have any PID that identifies it, the only way of interaction I have is finding manually the PID of the testCommand.py and then executing the appropriate signal via kill.
Does anyone know what I'm doing wrong here? I can go to the basics and start using C/C++ with the various system calls but I would really like to actually learn how to do this with PyQt4 and Python.
Thanks!
EDIT
It seems that startDetached() indeed returns True|False. The PID however is nowhere to be found...Not what one reads in the official documentation.
回答1:
The function startDetached
is overloaded in C++, it has several signatures. Depending on the arguments provided, it does not necesseraly return the same thing.
Even if overloading does not exist in Python, you have something similar:
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))
来源:https://stackoverflow.com/questions/31519215/pyqt4-qprocess-startdetached-cant-get-return-value-and-pid-of-spawned-proce