[PyQt] isRunning() returns true after QThread completion
Hans-Peter Jansen
hpj at urpla.net
Sun Feb 26 21:06:30 GMT 2012
Dear Lars,
On Sunday 26 February 2012, 15:55:25 Lars Beiderbecke wrote:
> Hello,
>
> In my application some QThreads still return isRunning() == true when
> they should be completed.
>
> More specifically, I'm using QThreads to load images asynchronously
> in the background. By emitting a signal, the thread notifies the
> main window that the pixmap has been loaded and the corresponding
> widget can be updated (code has been simplified):
>
> class ImgRequest(QtCore.QThread):
> def run(self):
> # ... load image ...
> self.emit(QtCore.SIGNAL("sigDone"), self)
>
> class MainWindow(QtGui.QMainWindow):
> self.requests = set()
>
> def request(self, filename):
> t = ImgRequest(self, filename)
> self.connect(t, QtCore.SIGNAL("sigDone"), self.ack)
> self.requests.add(t)
> t.start()
>
> def ack(self, t):
> # ... update image ...
> if t.isRunning():
> print "WARNING: thread still running"
> t.wait()
> self.requests.remove(t)
>
> When I run above code, however, I'll often get WARNING messages,
> i.e., QThread.isRunning() is returning true even though its
> corresponding run() method has been completed.
>
> Is this merely a race condition between the signal and the actual
> completion of run(), or am I missing something fundamental about
> QThreads? Do I really need isRunning() and wait()?
Since you don't provide a runnable snippet, all I can do is guessing:
check out the Qt.ConnectionType parameter of connect, especially
QueuedConnection and BlockingQueuedConnection, and see, if they do,
what you're after.
While at it, please check out
http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/new_style_signals_slots.html
to further improve your code.
> And finally, is
> there a better way to deal with the QThread objects than storing them
> in a set so that the GC won't kill them while running?
Any scheme, that keeps the thread object reference alive, is fine.
BTW, the definition of your requests object is wrong. Either initialize
it as an instance variable in __init__ or any subsequent method, or as
a class variable omitting self. For the sake of clean code, I would
prefer the latter, even in the light of a single instance QMainWindow.
Finally, you should limit the number of threads to a sane maximum.
Pete
More information about the PyQt
mailing list