QProcess readyReadStandardOutput does not disconnect even after process termination!
using PySide 1.2.1 with Python 3.3.1 and Qt 4.8.4 on Ubuntu 13.04
I am trying to prototype something like an antivirus gui and I want to have real time output of the virus scan process. Since I do not want the GUI to become unresponsive during the scan process I am trying to execute the scan process in its own thread, while real-time output is sent to a widget through signals. The code structure is as follows:
def init(self, scanPath, scanParam, parent=None):
def run(self): self.finished.connect.(self.onThreadFinish) # to check thread termination self.theScanProc = QtCore.QProcess() self.theScanProc.readyReadStandardOutput.connect(self.printOut) self.theScanProc.finished.connect(self.onScanProcFinish) # to clean up process self.theScanProc.start(["scanprocess", [scanPath, scanParam]) self.exec_()
if (self.theScanProc.state() == QtCore.QProcess.ProcessState.Running) | (self.theScanProc.state() == QtCore.QProcess.ProcessState.Starting):
self.theLine = self.theScanProc.readAllStandardOutput()
self.sigWriteScan.emit(str(theLine)) # an appropriate method (from a different module) printing to widget registers with that signal
else: # THE ELSE CLAUSE, RELATED TO POINT A - SEE BELOW__
print("DID NOT MANAGE TO RETRIEVE LINE")
print("BYTES AVAILABLE: " + str(self.theScanProc.bytesAvailable()))
print("AT END: " + str(self.theScanProc.atEnd()))
except UnicodeDecodeError as uerr:
print ("A Unicode error occurred: " + str(uerr))
except Exception as genericerror:
print("A generic error occurred: " + str(genericerror))
# self.theScanProc.close() - have tried all combinations of commented lines with kill()
def onThreadFinish(self): # have also tried not to use this method to explicitly exit the thread self.exit()
The problem is twofold:
A) Even after the first time code enters the else clause in printOut method (i.e. process is no more Starting or Running) printOut gets called a few times more (even if the onScanProcFinish gets called that should somehow terminate / kill the process). It seems like there is some output left and the signal FAILS TO DISCONNECT even after killing / terminating the scan process? Something like an unpredictable buffering situation?????
At those subsequent unexpected calls of printOut, bytes available always returns 0 and atEnd() is always True
B) Sometimes I get a segmentation fault! I have really no clue where this comes from!
There SEEMS to be a connection with this issue
but on one hand I am using Qt 4.8.4 and on the other hand I don't experience the exact same behaviour but rather I do get all (buffered?) data and some extra unexplained calls to the method bound to readyReadStandardOutput (event after killing / closing the process)!!!
Many thanks in advance for your time
The first problem, i.e. subsequent calls to the slot connected to readyReadStandardOutput seems to be addressed by using the signal readyRead, i.e. line 8 now becomes
and the QProcess method called inside the respective slot reads just the exact number of available bytes, i.e. line 17 becomes
self.theLine = self.theScanProc.read(self.theScanProc.bytesAvailable())
Segmentation fault issue remains
A new (very peculiar) finding though is the following:
I have connected destroyed signal of theScanProc to a slot through the line
which just prints out a "PROCESS DESTROYED METHOD"
The (very strange) result is the following:
The process gets called ONLY WHEN THE MAIN WINDOW IS CLOSED (application exits) and even this does not happen all the time.
I.e. it may so happen that the entire application is shut down and the destroyed signal does not get emitted?!!!!
The big question that arises now is the following: is the overall approach correct: calling a antivirus scan process as a QProcess object INSIDE a QThread object?