Results 1 to 2 of 2

Thread: PyQt: Proper use of QRunnable and SIGNALs

  1. #1
    Join Date
    Jun 2008
    Posts
    88
    Thanks
    4
    Thanked 4 Times in 3 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11
    Wiki edits
    1

    Default PyQt: Proper use of QRunnable and SIGNALs

    Well managed threading in PyQt can be somewhat challenging. I love QThread for simple background tasks, but when you want to utilize all of the CPUs in a balanced fashion it becomes difficult. You can either create N number of thread instances to do the work, but if you're application has more than one service that wants to make use of background threads at the same time, there can be contention and your machine comes to a halt.

    So then there's the QThreadPool, which is a cool idea, but it only accepts QRunnable instances, which do not inherit from QObject, and hence cannot emit SIGNALs. I have a few ideas on how to properly emit SIGNALs from a QRunnable but I also have some concerns about thread safety, and whether or not there's a better way to do this in PyQt. C++ Qt provides nice things like QFuture and QFutureWatcher, but are unsupported in PyQt because of its reliance on C++ templates that apparently do not lend themselves well to Python.

    I derive my own class off of QRunnable and create a QObject as a member variable, used for emitting signals. My concern is that, because I'm creating the emitter in the constructor of my runnable, the emitter technically belongs to the thread it was created in. Therefore, if emit a signal with the QObject in the runnable's "run()" method, then I'm probably causing threading issues by calling "emit(...)" on the QObject in a background thread.

    Plan A:
    Qt Code:
    1. class MyRunnable(QtCore.QRunnable):
    2. def __init__(self):
    3. QtCore.QRunnable.__init__(self)
    4. self.emitter = QtCore.QObject() # 'owned' by the thread it was created in
    5.  
    6. def run(self):
    7. # do stuff in a bg thread
    8.  
    9. # is this bad? emitter technically doesnt emit the signal from the background thread
    10. # it emits the signal from the thread it was created in. Also, according to the documentation
    11. # you cannot call self.emitter.moveToThread(QtCore.QThreadPool.currentThread()) here
    12. self.emitter.emit(SIGNAL("finshed()"))
    To copy to clipboard, switch view to plain text mode 


    I suppose another option would be to pass in the function you want to connect to and create the emitter in the "run()" method

    Plan B:
    Qt Code:
    1. class MyRunnable(QtCore.QRunnable):
    2. def __init__(self, callback):
    3. QtCore.QRunnable.__init__(self)
    4. self._callback = callback
    5.  
    6. def run(self):
    7. self.emitter = QtCore.QObject()
    8. self.emitter.connect(SIGNAL("finished()"), self._callback)
    9.  
    10. # do stuff in a bg thread
    11.  
    12. # thread safe way to connect to the callback
    13. self.emitter.emit(SIGNAL("finshed()"))
    To copy to clipboard, switch view to plain text mode 

    Is one way better than the other? Is there a better way?
    Last edited by chezifresh; 28th October 2011 at 02:24.

  2. #2
    Join Date
    Jun 2008
    Posts
    88
    Thanks
    4
    Thanked 4 Times in 3 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11
    Wiki edits
    1

    Default Re: PyQt: Proper use of QRunnable and SIGNALs

    I think I can simplify the question a bit.

    Is it okay for a QObject to emit a SIGNAL from a different thread than the one it was created in? And are there any consequences for that? ie. will the recipient's SLOT be executed in the thread where the SIGNAL was emitted from?

Similar Threads

  1. Use QRunnable without QThreadPool
    By Qiieha in forum Qt Programming
    Replies: 2
    Last Post: 18th August 2011, 10:02
  2. PyQt: the old style signals are not working
    By ravi.xolve in forum Qt Programming
    Replies: 0
    Last Post: 29th April 2011, 07:27
  3. How to emit signals from QRunnable?
    By mlheese in forum Newbie
    Replies: 1
    Last Post: 29th July 2010, 23:26
  4. QRunnable - how to cancel execution?
    By TorAn in forum Qt Programming
    Replies: 1
    Last Post: 3rd March 2010, 19:11
  5. QThreadPool and QRunnable
    By jimc1200 in forum Qt Programming
    Replies: 3
    Last Post: 6th May 2009, 10:43

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.