Page 2 of 2 FirstFirst 12
Results 21 to 26 of 26

Thread: Main thread - worker thread communication.

  1. #21
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Main thread - worker thread communication.

    Are you sure this is correct?
    Qt Code:
    1. class WorkerThread(QtCore.QThread):
    2. def __init__(self, start, end):
    3. QtCore.QThread.__init__(self)
    4. self.start = start
    5. self.end = end
    To copy to clipboard, switch view to plain text mode 
    You have a variable called start and then you call start as a method. Try using a different name here. Maybe that's the problem.

  2. The following user says thank you to wysota for this useful post:

    kikapu (22nd May 2007)

  3. #22
    Join Date
    May 2007
    Posts
    23
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Main thread - worker thread communication.

    Quote Originally Posted by wysota View Post
    Are you sure this is correct?
    Qt Code:
    1. class WorkerThread(QtCore.QThread):
    2. def __init__(self, start, end):
    3. QtCore.QThread.__init__(self)
    4. self.start = start
    5. self.end = end
    To copy to clipboard, switch view to plain text mode 
    You have a variable called start and then you call start as a method. Try using a different name here. Maybe that's the problem.
    ...
    .....
    .......

    What can i say...i am just an idiot...The problem was right just under my nose. That was it! I renamed start to pstart and all working ok.
    A MILLION thanks wysota!!!

    I will now just experiment with the "proxy" style to send the signal.

    Thanks again!
    Software Engineer, riding a Kona King Kikapu 2007

  4. #23
    Join Date
    May 2007
    Posts
    23
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Main thread - worker thread communication.

    I have made an exact (i hope) Python version of your C++ code, i post it below.
    The thing seems to be working ok, the progress bar is updated correctly and the main thread (form) remains responsive.
    (I do not like the fact that i use 3 classes just to do that but anyway...)

    So, we connect the propagate SIGNAl to the Emiter one and thus we get the SLOT setValue of the progress bar to be fired when the SIGNAL is sent.

    In a previous version of mine, you have said that in the way i had wrote it was a little dangerous because we might not be sure from what thread the code will be executed.
    As i study more closely your code (and my Python implementation of this), what make you sure that in this way the function will be called from the correct thread ?


    Here is the code:

    Qt Code:
    1. import sys
    2. from PyQt4 import QtCore, QtGui
    3. from calculatorform_ui import Ui_CalculatorForm
    4. from ui_countNumbers import Ui_MainWindow
    5. from time import sleep
    6.  
    7. class Emiter(QtCore.QObject):
    8. def __init__(self):
    9. QtCore.QObject.__init__(self)
    10.  
    11. def emitSignal(self, val):
    12. self.emit(QtCore.SIGNAL("updateProgress(int)"), val)
    13.  
    14. class WorkerThread(QtCore.QThread):
    15. def __init__(self):
    16. QtCore.QThread.__init__(self)
    17. self.pstart = 0
    18. self.pend = 0
    19.  
    20. def run(self):
    21. e = Emiter()
    22. propagate = QtCore.SIGNAL("propagate(int)")
    23. QtCore.QObject.connect(e, QtCore.SIGNAL("updateProgress(int)"), self, propagate)
    24.  
    25. for x in range(self.pstart, self.pend):
    26. sleep(1)
    27. e.emitSignal(x)
    28.  
    29. class CountNumbersForm(QtGui.QMainWindow):
    30. def __init__(self, parent=None):
    31. QtGui.QMainWindow.__init__(self, parent)
    32. self.ui = Ui_MainWindow()
    33. self.ui.setupUi(self)
    34.  
    35. @QtCore.pyqtSignature("")
    36. def on_start_clicked(self):
    37. worker.pstart = count.ui.spFrom.value()
    38. worker.pend = count.ui.spTo.value() + 1
    39. self.ui.progress.setRange(worker.pstart, worker.pend)
    40. worker.start()
    41.  
    42. def updateProgress(self, val):
    43. self.ui.progress.setValue(val)
    44.  
    45.  
    46. if __name__ == "__main__":
    47. app = QtGui.QApplication(sys.argv)
    48. count = CountNumbersForm();
    49. worker = WorkerThread();
    50. QtCore.QObject.connect(worker, QtCore.SIGNAL("propagate(int)"), count.ui.progress.setValue, QtCore.Qt.QueuedConnection)
    51. count.show()
    52. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 


    I mean, if i emit entirely the Emit class and the like and replace WorkerThread class with this:
    Qt Code:
    1. class WorkerThread(QtCore.QThread):
    2. def __init__(self):
    3. QtCore.QThread.__init__(self)
    4. self.pstart = 0
    5. self.pend = 0
    6.  
    7. def run(self):
    8. for x in range(self.pstart, self.pend):
    9. sleep(1)
    10. self.emit(QtCore.SIGNAL("updateProgress(int)"), x)
    To copy to clipboard, switch view to plain text mode 


    what do you think will go wrong ? I read PyQt4 docs and says that the mechanism is able to "Connections may be made across threads." Isn't it our occassion here and particularly because i use queued connections ?? (QtCore.Qt.QueuedConnection)

    Thanks again!
    Last edited by kikapu; 23rd May 2007 at 14:23.
    Software Engineer, riding a Kona King Kikapu 2007

  5. #24
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Main thread - worker thread communication.

    If you force queued connections, then all will be ok. The thing that makes me sure my approach will work is that the "emit" object is created (and thus handled) in the worker thread (because it's created in the run() method that is executed in context of the worker thread). This means that if I call a method that emits a signal and both the caller (run()) and the callee (Emit instance) are in the same (worker) thread, I can be sure that the signal will be queued because the receiver is in the GUI thread. Now if the callee (QThread object) was in a different thread than the caller (run()) I don't know how Qt would behave. You can check Qt sources and see for yourself - maybe the trick I made was not needed. You can also have the same effect without the Emit object - just move the QThread object to the thread it represents.

  6. #25
    Join Date
    May 2007
    Posts
    23
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Main thread - worker thread communication.

    Quote Originally Posted by wysota View Post
    If you force queued connections, then all will be ok. The thing that makes me sure my approach will work is that the "emit" object is created (and thus handled) in the worker thread (because it's created in the run() method that is executed in context of the worker thread). This means that if I call a method that emits a signal and both the caller (run()) and the callee (Emit instance) are in the same (worker) thread, I can be sure that the signal will be queued because the receiver is in the GUI thread. Now if the callee (QThread object) was in a different thread than the caller (run()) I don't know how Qt would behave. You can check Qt sources and see for yourself - maybe the trick I made was not needed. You can also have the same effect without the Emit object - just move the QThread object to the thread it represents.
    Ok, i see...very helpfull post indeed. The "queued connections", as i saw it, are a very nice way to keep things simple and not complicated. regarding the Singals and Slots mechanism and the communication over different threads. (In fact, i like it even more that the respective C# stuff)
    Is there any "catch" with that ? Performance problems or something else ?
    Software Engineer, riding a Kona King Kikapu 2007

  7. #26
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Main thread - worker thread communication.

    They are a bit slower as you have to serialise all the arguments and then recreate them back in the other thread when the slot is executed. And there is of course the latency between emiting the signal and the other thread processing it. Oh... and the other thread has to have an event loop running of course.

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.