Results 1 to 20 of 38

Thread: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    Quote Originally Posted by prof.ebral View Post
    As far as I understand data sent by signals is sent to the main thread.
    There are two things here. "Data" (as in arguments to signals) are not sent to any thread, in the meaning that thread affinity of them does not change in any way. If you pass a pointer to a QObject that lives in thread A to thread B, then accessing that object there might cause data corruption or worse. If you pass some non-QObject by pointer then it doesn't have any thread affinity and it is its thread-safety that decides whether this is safe or not. if you pass a non-QObject by value then it is copied and in regular cases will have no notion of its other clone being accessed from the original thread. However another topic is if we interpret what you said as "signals are sent to the main thread" in which case this is not true -- signals are sent in the thread they are emitted in (it's just a plain function call) but connecting to them may cause an event to be posted to an object living in a different thread (it doesn't have to be the "main" thread though).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  2. #2
    Join Date
    Feb 2010
    Posts
    96
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 5 Times in 5 Posts

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    Quote Originally Posted by wysota View Post
    However another topic is if we interpret what you said as "signals are sent to the main thread" in which case this is not true -- signals are sent in the thread they are emitted in (it's just a plain function call) but connecting to them may cause an event to be posted to an object living in a different thread (it doesn't have to be the "main" thread though).
    Hmmm, I thought the main thread received the signal as a handler and then executed the method defined by the slot.

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

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    Quote Originally Posted by prof.ebral View Post
    Hmmm, I thought the main thread received the signal as a handler and then executed the method defined by the slot.
    No, it depends on the thread affinity of the object that the slot belongs to. Here is a simple example:

    Qt Code:
    1. #include <QtCore>
    2.  
    3. class Object : public QObject {
    4. Q_OBJECT
    5. public:
    6. Object(QObject *parent = 0) : QObject(parent) {
    7.  
    8. }
    9. public slots:
    10. void reportThread() {
    11. qDebug() << Q_FUNC_INFO << QThread::currentThread();
    12. }
    13. };
    14.  
    15. #include "main.moc"
    16.  
    17. int main(int argc, char **argv) {
    18. QCoreApplication app(argc, argv);
    19.  
    20. QVector<QThread*> threads;
    21. QVector<Object*> objects;
    22. for(int i=0;i<4;++i) {
    23. QThread *thr = new QThread;
    24. threads << thr;
    25.  
    26. Object *o = new Object;
    27. o->moveToThread(thr);
    28. objects << o;
    29.  
    30. thr->start();
    31.  
    32. }
    33. // last object in main thread
    34. objects << new Object;
    35. qDebug() << "GUI thread:" << objects.last()->thread();
    36. QTimer t;
    37. t.start(2000);
    38. foreach(Object *o, objects)
    39. QObject::connect(&t, SIGNAL(timeout()), o, SLOT(reportThread()));
    40. return app.exec();
    41. }
    To copy to clipboard, switch view to plain text mode 

    You can also move the timer to one of the threads and see if it changes anything.

    Oh, one more thing -- you can run this example under a debugger, set a breakpoint in the slot and look at the backtrace. You'll see how it differs for the last added object (the one that lives in the main thread) compared to other objects.
    Last edited by wysota; 11th December 2012 at 22:20.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  4. #4
    Join Date
    Feb 2010
    Posts
    96
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 5 Times in 5 Posts

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    Ok, thanks wysota. I use PyQt and when I look at the current thread inside a method that has been called by a signal it is the main thread. I've yet to see an instance when it is isn't in PyQt.

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

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    Quote Originally Posted by prof.ebral View Post
    Ok, thanks wysota. I use PyQt and when I look at the current thread inside a method that has been called by a signal it is the main thread. I've yet to see an instance when it is isn't in PyQt.
    Maybe you are using Python threads and not QThreads. I have no idea how Qt will behave then.

    I ran this test program:

    python Code:
    1. from PySide import QtCore
    2. import sys
    3.  
    4. class Object(QtCore.QObject):
    5. def reportThread(self):
    6. print(QtCore.QThread.currentThread())
    7.  
    8. app = QtCore.QCoreApplication(sys.argv)
    9. thr = QtCore.QThread()
    10. obj = Object()
    11.  
    12. timer = QtCore.QTimer()
    13. print("MainThread"+str(QtCore.QThread.currentThread()))
    14. timer.timeout.connect(obj.reportThread)
    15. timer.start(2000)
    16. app.exec_()
    To copy to clipboard, switch view to plain text mode 

    and it behaves the same way as I described:

    MainThread<PySide.QtCore.QThread object at 0xf6a050>
    <PySide.QtCore.QThread object at 0xf6a0e0>
    <PySide.QtCore.QThread object at 0xf6a0e0>
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #6
    Join Date
    Feb 2010
    Posts
    96
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 5 Times in 5 Posts

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    This is the output I get
    Qt Code:
    1. MainThread<PyQt4.QtCore.QThread object at 0x7f16ef83c408>
    2. <PyQt4.QtCore.QThread object at 0x7f16ef83c408>
    To copy to clipboard, switch view to plain text mode 
    The main thread is located at the same memory allocation as all of the other threads.

    edit: By the way, here is the changed code for PyQt
    Qt Code:
    1. from PyQt4 import QtCore
    2. import sys
    3.  
    4. class Object(QtCore.QObject):
    5. def reportThread(self):
    6. print(QtCore.QThread.currentThread())
    7.  
    8. app = QtCore.QCoreApplication(sys.argv)
    9. thr = QtCore.QThread()
    10. obj = Object()
    11.  
    12. timer = QtCore.QTimer()
    13. print("MainThread"+str(QtCore.QThread.currentThread()))
    14. timer.timeout.connect(obj.reportThread)
    15. timer.start(2000)
    16. app.exec_()
    To copy to clipboard, switch view to plain text mode 
    Not much different.

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

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    Maybe that's an issue with PyQt4 (I would rather suspect that it returns an incorrect thread pointer rather than runs the slot in a wrong thread). As you can see I was using PySide.


    Edit: LOL... I forgot to move the object to the thread and start the thread

    Here is a working version:

    python Code:
    1. from PyQt4 import QtCore
    2. import sys
    3.  
    4. class Object(QtCore.QObject):
    5. def __init__(self):
    6. QtCore.QThread.__init__(self)
    7.  
    8. def reportThread(self):
    9. print(QtCore.QThread.currentThreadId())
    10.  
    11. app = QtCore.QCoreApplication(sys.argv)
    12. thr = QtCore.QThread()
    13. obj = Object()
    14. obj.moveToThread(thr)
    15. thr.start()
    16.  
    17. timer = QtCore.QTimer()
    18. print("MainThread"+str(QtCore.QThread.currentThreadId()))
    19. timer.timeout.connect(obj.reportThread)
    20. timer.start(2000)
    21.  
    22. t2 = QtCore.QTimer()
    23. t2.timeout.connect(app.quit)
    24. t2.start(10000)
    25. app.exec_()
    To copy to clipboard, switch view to plain text mode 
    Last edited by wysota; 11th December 2012 at 23:16.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. #8
    Join Date
    Feb 2010
    Posts
    96
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 5 Times in 5 Posts

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    Quote Originally Posted by wysota View Post
    Maybe that's an issue with PyQt4 (I would rather suspect that it returns an incorrect thread pointer rather than runs the slot in a wrong thread). As you can see I was using PySide.
    I think it is a feature of PyQt. I'll have to check over the documentation again, but I think PyQt signals and slots operate 'through' the main thread. Like how I described before. Sorry for adding confusion to the post.

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

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    No, it's not a feature of PyQt. Look at my previous post, I just edited it.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  10. #10
    Join Date
    Feb 2010
    Posts
    96
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 5 Times in 5 Posts

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    That doesn't work for me. I only receive the MainThread print statement in my terminal.

    edit: wysota, here is some modified code and the output. Even after the Object class is moved to the Thread class I still get the main thread's ID ... but for me the signal is not being caught by the Object's reportThread method.

    Qt Code:
    1. from PyQt4 import QtCore
    2. import sys, time
    3.  
    4. class Object(QtCore.QObject):
    5. def __init__(self):
    6. QtCore.QObject.__init__(self)
    7.  
    8. def reportThread(self):
    9. print self, (QtCore.QThread.currentThreadId())
    10.  
    11. class Thread(QtCore.QThread):
    12. def __init__(self):
    13. QtCore.QThread.__init__(self)
    14.  
    15. def reportThread(self):
    16. print self, (QtCore.QThread.currentThreadId())
    17.  
    18. app = QtCore.QCoreApplication(sys.argv)
    19. thr = Thread()
    20. obj = Object()
    21. obj.moveToThread(thr)
    22. print obj, obj.thread(), obj.thread().currentThreadId()
    23. thr.start()
    24.  
    25. timer = QtCore.QTimer()
    26. print ( "MainThread "+str(QtCore.QThread.currentThreadId()) )
    27. timer.timeout.connect(obj.reportThread)
    28. timer.timeout.connect(thr.reportThread)
    29. timer.start(2000)
    30.  
    31. t2 = QtCore.QTimer()
    32. t2.timeout.connect(app.quit)
    33. t2.start(10000)
    34. app.exec_()
    To copy to clipboard, switch view to plain text mode 

    output:
    Qt Code:
    1. <__main__.Object object at 0xabd2f8> <__main__.Thread object at 0xabd270> 140273089054464 MainThread 140273089054464
    2. <__main__.Thread object at 0xabd270> 140273089054464
    3. <__main__.Thread object at 0xabd270> 140273089054464
    4. <__main__.Thread object at 0xabd270> 140273089054464
    5. <__main__.Thread object at 0xabd270> 140273089054464
    6. <__main__.Thread object at 0xabd270> 140273089054464
    To copy to clipboard, switch view to plain text mode 
    Last edited by prof.ebral; 11th December 2012 at 23:54.

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

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    Quote Originally Posted by prof.ebral View Post
    That doesn't work for me. I only receive the MainThread print statement in my terminal.

    edit: wysota, here is some modified code and the output. Even after the Object class is moved to the Thread class I still get the main thread's ID ...
    That's because the Thread object lives in the main thread. You only moved the Object instance to the thread, not the Thread instance. There is a distinction between a thread (as in a separate processing flow) and QThread instance.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  12. #12
    Join Date
    Feb 2010
    Posts
    96
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 5 Times in 5 Posts

    Default Re: Need Qt SerialPort class example using signals and slots WITHIN A THREAD

    Quote Originally Posted by wysota View Post
    That's because the Thread object lives in the main thread. You only moved the Object instance to the thread, not the Thread instance. There is a distinction between a thread (as in a separate processing flow) and QThread instance.
    >____< I used the code you gave me. "I" did not do that. Anyway, thank you.

Similar Threads

  1. Signals Slots and Class Pointers
    By Atomic_Sheep in forum Newbie
    Replies: 18
    Last Post: 7th September 2012, 10:08
  2. [Signals & Slots] Custom class' signal not detected
    By Mr_Cloud in forum Qt Programming
    Replies: 5
    Last Post: 26th July 2012, 11:35
  3. Thread safety with signals and slots
    By blooglet in forum Qt Programming
    Replies: 1
    Last Post: 15th March 2012, 16:03
  4. Are signals and slots thread safe?
    By Cruz in forum Qt Programming
    Replies: 12
    Last Post: 21st April 2011, 15:57
  5. Access a class without using Signals/Slots
    By impeteperry in forum Qt Programming
    Replies: 5
    Last Post: 10th January 2010, 12:14

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