[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