Results 1 to 20 of 26

Thread: Main thread - worker thread communication.

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 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.

    We won't know unless you implement the thread. The thread needs to emit a signal that will update the progress bar. I don't see that in your code.

  2. #2
    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
    We won't know unless you implement the thread. The thread needs to emit a signal that will update the progress bar. I don't see that in your code.
    Xmm,...ok, i do this now. But, isn't the postEvent/customEvent thing a viable mechanism to do such things ??
    Software Engineer, riding a Kona King Kikapu 2007

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 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.

    You can use custom events but using signals is simpler. They use the event mechanism behind the scenes, so the result is the same, just less coding.

  4. #4
    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
    You can use custom events but using signals is simpler. They use the event mechanism behind the scenes, so the result is the same, just less coding.
    Ok the...I try to make it your way and i post the revised code below. I get the same error message as before: "TypeError: 'int' object is not callable" at t.start() line.

    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 WorkerThread(QtCore.QThread):
    8. def __init__(self, form, start, end):
    9. QtCore.QThread.__init__(self)
    10. self.start = start
    11. self.end = end
    12. self.form = form
    13.  
    14. def run(self):
    15. c = C()
    16. QtCore.QObject.connect(form.ui.progressBar, c.update, form, QtCore.SLOT("setValue(int)"))
    17.  
    18. for x in range(start, end):
    19. c.emit(c.update, x)
    20.  
    21. class C(QtCore.QObject):
    22. update = QtCore.SIGNAL("update(int)")
    23.  
    24.  
    25. class CountNumbersForm(QtGui.QMainWindow):
    26. def __init__(self, parent=None):
    27. QtGui.QMainWindow.__init__(self, parent)
    28. self.ui = Ui_MainWindow()
    29. self.ui.setupUi(self)
    30.  
    31. @QtCore.pyqtSignature("")
    32. def on_start_clicked(self):
    33. t = WorkerThread(self, self.ui.spFrom.value(), self.ui.spTo.value() + 1);
    34. t.start()
    To copy to clipboard, switch view to plain text mode 

    I am very much frustrated here...
    Software Engineer, riding a Kona King Kikapu 2007

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

    Default Re: Main thread - worker thread communication.

    After a lot of study, i now coded it more correctly (i think) but strangely enough i get the same error message as before. ('int' object is not callable" at t.start() )

    Code is:

    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 WorkerThread(QtCore.QThread):
    8. def __init__(self, start, end):
    9. QtCore.QThread.__init__(self)
    10. self.start = start
    11. self.end = end
    12.  
    13. def run(self):
    14. for x in range(start, end):
    15. self.emit(QtCore.SIGNAL("updateProgress"), x)
    16.  
    17.  
    18. class CountNumbersForm(QtGui.QMainWindow):
    19. def __init__(self, parent=None):
    20. QtGui.QMainWindow.__init__(self, parent)
    21. self.ui = Ui_MainWindow()
    22. self.ui.setupUi(self)
    23.  
    24. @QtCore.pyqtSignature("")
    25. def on_start_clicked(self):
    26. worker = WorkerThread(self.ui.spFrom.value(), self.ui.spTo.value() + 1);
    27. QtCore.QObject.connect(worker, QtCore.SIGNAL("updateProgress"), self.updateProgress, QtCore.Qt.QueuedConnection)
    28. worker.start()
    29.  
    30. def updateProgress(self, val):
    31. self.ui.progres.setValue(val)
    32.  
    33.  
    34. if __name__ == "__main__":
    35. app = QtGui.QApplication(sys.argv)
    36. count = CountNumbersForm();
    37. count.show()
    38. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 
    Software Engineer, riding a Kona King Kikapu 2007

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 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.

    What is class C?

    I can give you a draft of C++ code that does what you want. Then you can translate it into python, as my python skills are a bit stale...

    Qt Code:
    1. class Emiter : public QObject {
    2. Q_OBJECT
    3. public:
    4. Emiter(QObject *parent=0) : QObject(parent){}
    5. void emitSignal(int v){ emit sig(v); }
    6. signals:
    7. void sig(int);
    8. };
    9. class MyThread : public QThread {
    10. Q_OBJECT
    11. public:
    12. MyThread(QObject *parent =0) : QThread(parent){}
    13. void run() {
    14. Emiter e;
    15. connect(&e, SIGNAL(sig(int)), this, SIGNAL(propagate(int)));
    16. i=0;
    17. while(i<=100){
    18. sleep(1);
    19. e.emitSignal(i++);
    20. }
    21. }
    22. signals:
    23. void propagate(int);
    24. };
    25.  
    26. //...
    27. MyThread thread;
    28. connect(&thread, SIGNAL(propagate(int)), &pbar, SLOT(setValue(int)));
    29. thread.start();
    To copy to clipboard, switch view to plain text mode 
    Of course there are other ways to do the same thing, for example the propagate() signal is not needed, you can connect the original signal directly to the progress bar if you have access to it.

  7. #7
    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
    What is class C?
    There is no class C anymore (see my just above post for a more correct solution). Ok, i try to translate your C code although i think that the last Python version i posted is very much alike...
    Software Engineer, riding a Kona King Kikapu 2007

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 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.

    The code you posted is dangerous because you emit a signal from a worker thread on account of an object that is in the gui thread and I have no idea in context of which thread the signal will be emitted and will it be queued or executed directly. My Emiter class makes sure the context of the worker thread is used and the signal is queued and propagated in the context of the GUI thread.

  9. #9
    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
    The code you posted is dangerous because you emit a signal from a worker thread on account of an object that is in the gui thread
    But isn't the whole idea ?? In C# we use delegates to do that, in Qt i hoped that with Signals and Slots i will be able to do it. I think that Qt automatically find the correct thread to "use".

    Your Emiter class is "translated" to Python like this ?
    Qt Code:
    1. class Emiter(QtCore.QObject):
    2. def __init__(self):
    3. QObject.__init__(self)
    4.  
    5. def emitSignal(self, val):
    6. self.emit(QtCore.SIGNAL("updateProgress"), x)
    To copy to clipboard, switch view to plain text mode 

    And what is the purpose (and implementation as it is not shown how it does it's work) of MyThread:: propagate ? Just to forward the signal ?

    I think i am stuck...
    Last edited by kikapu; 22nd May 2007 at 15:35.
    Software Engineer, riding a Kona King Kikapu 2007

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 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.

    Quote Originally Posted by kikapu View Post
    But isn't the whole idea ?? In C# we use delegates to do that, in Qt i hoped that with Signals and Slots i will be able to do it. I think that Qt automatically find the correct thread to "use".
    Yes, but I'm not sure what it will decide when you call a function from an object that lives in another thread. It might work, but I'm not sure, therefore I used this kind of "proxy".

    Your Emiter class is "translated" to Python like this ?
    Qt Code:
    1. class Emiter(QtCore.QObject):
    2. def __init__(self):
    3. QObject.__init__(self)
    4.  
    5. def emitSignal(self, val):
    6. self.emit(QtCore.SIGNAL("updateProgress"), x)
    To copy to clipboard, switch view to plain text mode 
    Looks correct.


    And what is the purpose (and implementation as it is not shown how it does it's work) of MyThread:: propagate ? Just to forward the signal ?
    Yes, just to forward the signal. As I mentioned, you could do it without it, but then you'd have to have access to the progress bar from within the thread object. That's your choice.

  11. #11
    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
    Yes, just to forward the signal. As I mentioned, you could do it without it, but then you'd have to have access to the progress bar from within the thread object. That's your choice.
    Yes, i now what you mean, we sometimes use it in .net too. But i am afraid i can not go too far, every solution that i implement, i see this error "TypeError: 'int' object is not callable"

    I really feel like an idiot, i have written countless thousands lines of code in my life and i am stucked in 10 lines of this. What can i say...
    Software Engineer, riding a Kona King Kikapu 2007

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 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.

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

    kikapu (22nd May 2007)

  14. #13
    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

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
  •  
Qt is a trademark of The Qt Company.