Results 1 to 5 of 5

Thread: QThread - multi threaded signals and slots

  1. #1
    Join Date
    Jan 2008
    Posts
    27
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QThread - multi threaded signals and slots

    Hi,

    I am trying to figure out how to emit a signal from one my threads to another thread, both non-gui threads. I see in the Qt documentation it is possible, I just cannot figure it out.

    Seems like I need something like, I am just not sure in the NetReceive class.
    connect(this, SIGNAL(checkNetQueue()), <ptr to other thread>, SLOT(processNetQueue()), Qt::QueuedConnection);

    Here is a little background on how my classes are setup:
    NetworkThread is a abstract parent class and I have two children from that thread, NetThread and NetReceiveThread. I want NetReceiveThread to emit a signal to the NetThread. If I emit the signal from NetThread itself, the slot executes and works fine.

    The threads are created in my Main GUI window as class variables, like NetThread t1, NetReceiveThread t2. And then start() is called on each of them inside the MainWin constructor.

    Any ideas you can come up? I appreciate the help.

    Thanks so much.
    RishiD

    ---------------------------------------------------------------------

    Here are some small snippets of my three thread headers.

    NetworkThread.h
    Qt Code:
    1. class NetworkThread : public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. NetworkThread() { };
    6. signals:
    7. void checkNetQueue();
    8.  
    9. };
    To copy to clipboard, switch view to plain text mode 

    NetThread.h
    Qt Code:
    1. class NetThread : public NetworkThread
    2. {
    3. Q_OBJECT
    4. public:
    5. NetThread();
    6.  
    7. protected:
    8. void run()
    9. {
    10. // emitting checkNetQueue() works fine, if the emit is run inside the NetThread
    11. connect(this, SIGNAL(checkNetQueue()), this, SLOT(processNetQueue()));
    12. exec();
    13. }
    14.  
    15. private slots:
    16. void processNetQueue();
    17. }
    To copy to clipboard, switch view to plain text mode 

    NetReceiveThread.h
    Qt Code:
    1. class NetReceiveThread : public NetworkThread
    2. {
    3. Q_OBJECT
    4. public:
    5. NetReceiveThread(){}
    6. protected:
    7. void run()
    8. {
    9. // need to change the second this, to a pointer to NetThread
    10. // connect(this, SIGNAL(checkNetQueue()), this, SLOT(processNetQueue()),
    11. // Qt::QueuedConnection);
    12. receiveLoop() // <--- calls emit checkNetQueue();
    13. }
    14.  
    15.  
    16. };
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QThread - multi threaded signals and slots

    Make
    Qt Code:
    1. connect(this, SIGNAL(checkNetQueue()), this, SLOT(processNetQueue()));
    To copy to clipboard, switch view to plain text mode 
    use direct connection instead:
    Qt Code:
    1. connect(this, SIGNAL(checkNetQueue()), this, SLOT(processNetQueue()), Qt::DirectConnection);
    To copy to clipboard, switch view to plain text mode 

    Otherwise the signal gets queued and processNextQueue() gets called in "wrong" thread context (because QThread lives in the creator thread, which is not same as QThread::run()).
    J-P Nurmi

  3. #3
    Join Date
    Jan 2008
    Posts
    27
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - multi threaded signals and slots

    Ok, that will fix that problem I was having where the QThread was actually calling the processNetQueue() which I did not want. I wanted the NetThread instance to take care of it.

    But for the receive thread, should I used a Queued connection or Direct? Right now it is working with Queued, but once again QThread is calling the slot. I am assuming I should change this to Direct?

    The code below is how I have it in the receive thread run() method. Where netThread is a pointer to the NetThread object that is created in the MainWin.

    Thanks for the help, once again jpn.

    Qt Code:
    1. connect(this, SIGNAL(checkNetQueue()), netThread,
    2. SLOT(processNetQueue()), Qt::QueuedConnection);
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QThread - multi threaded signals and slots

    There's the problem. Slots in QThread subclasses are very problematic. QThread object itself lives in different thread than QThread::run() is executed. Slots get called in the thread context where the receiver QObject lives. You can't fix it by changing connection type. I recommend you don't do anything else but allocate an object with required slots on the stack and call exec() in QThread::run(). This object will live in the worker thread and receive signals like you want.

    Qt Code:
    1. class MyThread : public QThread
    2. {
    3. ...
    4. void run()
    5. {
    6. Receiver recv; // <-- this object lives in the worker thread and receives signals "correctly"
    7. ...
    8. exec();
    9. }
    10. ...
    11. }
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  5. The following user says thank you to jpn for this useful post:

    rishid (30th March 2008)

  6. #5
    Join Date
    Jan 2008
    Posts
    27
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - multi threaded signals and slots

    Alright that does make sense. Time to restructure all my objects and threads, will report back if I have any problems.

    Thanks

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.