Results 1 to 11 of 11

Thread: Receiving slots in QThread's context ?

  1. #1
    Join Date
    Aug 2007
    Posts
    166
    Thanks
    16
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Receiving slots in QThread's context ?

    Hello,

    Is it possible signal emited from the main(or other) thread to be received in a slot inside the QThread context? I have failed to accomplish that so far...

    Here's what I'm basically doing:
    Qt Code:
    1. class MyThread : QThread
    2. {
    3. Q_OBJECT:
    4.  
    5. public:
    6. MyThread() {}
    7. ~MyThread() {}
    8.  
    9. void addNewStuff()
    10. {
    11. // This method is called from the main thread
    12. emit newStuff();
    13. }
    14.  
    15. protected:
    16. virtual void run()
    17. {
    18. connect( this, SIGNAL(newStuff()), this, SLOT(onNewStuff()) );
    19. exec();
    20. }
    21.  
    22. private slots:
    23. void onNewStuff()
    24. {
    25. // My slot also is called from the main thread... :(
    26. QThread::currentThreadId();
    27. }
    28.  
    29. signals:
    30. void newStuff();
    31. };
    To copy to clipboard, switch view to plain text mode 

    MyThread is created and started from the main thread. At some point the main thread will call addNewStuff() method which I'm expecting to call onNewStuff() in the MyThread context, not in the main thread's one. So far my slot is always called from the main thread context... I also tried changing the flags of the connect() method but with no luck.

    Any help will be appreciated.

  2. #2
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Receiving slots in QThread's context ?

    have a look at moveToThread

  3. #3
    Join Date
    Aug 2007
    Posts
    166
    Thanks
    16
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving slots in QThread's context ?

    I had. I guess that you are not suggesting to call moveToThread(this) in the run method, because I had read that this is wrong.
    Can you provide more details please?

  4. #4
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: Receiving slots in QThread's context ?

    Qt Code:
    1. connect( this, SIGNAL(newStuff()), this, SLOT(onNewStuff()) );
    To copy to clipboard, switch view to plain text mode 
    This makes no sense. You could call your local function direct...
    Since I don't know what you really want, here is a markup what you might search:
    Qt Code:
    1. main()
    2. {
    3. MyThread a;
    4. MyThread b;
    5. GuiClass mainWindow;
    6.  
    7. connect(&a, SIGNAL(someSignal()), &b, SLOT(someSlot()));
    8. connect(&mainWindow, SIGNAL(someSignal()), &a, SLOT(someSlot()));
    9. }
    To copy to clipboard, switch view to plain text mode 


    EDIT: Don't realized your last paragraph, what's about QMetaMethod::invokeMethod with Qt::AutoConnection/Qt::QueuedConnection?
    Last edited by Lykurg; 13th August 2010 at 22:48.

  5. #5
    Join Date
    Aug 2007
    Posts
    166
    Thanks
    16
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving slots in QThread's context ?

    Same result...

  6. #6
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Receiving slots in QThread's context ?

    Try this:
    Note that I didn't test this if it compiles.

    myobject.h
    Qt Code:
    1. #include <QObject>
    2.  
    3. class MyObject: public QObject
    4. {
    5. Q_OBJECT
    6.  
    7. public:
    8. MyObject(QObject *parent = 0);
    9.  
    10. public slots:
    11. void slotInMyObject();
    12. };
    To copy to clipboard, switch view to plain text mode 

    myobject.cpp
    Qt Code:
    1. #include "myobject.h"
    2.  
    3. MyObject::MyObject(QObject *parent)
    4. : QObject(parent)
    5. {
    6. }
    7.  
    8. void MyObject::slotInMyObject()
    9. {
    10. //Do something
    11. }
    To copy to clipboard, switch view to plain text mode 

    mywidget.h
    Qt Code:
    1. #include <QWidget>
    2.  
    3. class MyWidget : public QWidget
    4. {
    5. Q_OBJECT
    6.  
    7. public:
    8. MyWidget(QWidget *parent = 0);
    9.  
    10. signals:
    11. void signalFromMyWidget();
    12. };
    To copy to clipboard, switch view to plain text mode 

    mywidget.cpp
    Qt Code:
    1. MyWidget::MyWidget(QWidget *parent)
    2. : QWidget(parent)
    3. {
    4. }
    5.  
    6. ...
    To copy to clipboard, switch view to plain text mode 

    Emit a signal somewhere, but try to emit only signals when all objects are created in the main thread and all objects are moved to the correct thread. Otherwise you will pull your hair out.

    I have no idea if QThread starts the eventloop automatically. If not, use the following thread class.
    mythread.h
    Qt Code:
    1. #include <QThread>
    2.  
    3. class MyThread : public QThread
    4. {
    5. public:
    6. void run();
    7. };
    To copy to clipboard, switch view to plain text mode 

    mythread.cpp
    Qt Code:
    1. void MyThread::run()
    2. {
    3. exec();
    4. }
    To copy to clipboard, switch view to plain text mode 

    Then put it all together:

    main.cpp
    Qt Code:
    1. #include "myobject.h"
    2. #include "mywidget.h"
    3. #include "mythread.h"
    4.  
    5. int main(...)
    6. {
    7. QApplication a(...);
    8.  
    9. MyWidget *w = new MyWidget;
    10. MyObject *o = new MyObject;
    11. MyThread *t = new MyThread;
    12.  
    13. connect(w, SIGNAL(signalFromMyWidget()), o, SLOT(slotInMyObject()));
    14.  
    15. o->moveToThread(t);
    16.  
    17. t->start();
    18.  
    19. w->show();
    20.  
    21. return a.exec();
    22. }
    To copy to clipboard, switch view to plain text mode 

    I might have forgotten something, but that's the basics.

  7. The following user says thank you to tbscope for this useful post:

    The Storm (14th August 2010)

  8. #7
    Join Date
    Aug 2007
    Posts
    166
    Thanks
    16
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving slots in QThread's context ?

    Thanks, this one worked. I just wonder why it can't be done with my QThread subclass... Anyway QThread automatically starts an event loop so instead of inheriting QThread I will just use QObject with regular QThread instance.

  9. #8
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Receiving slots in QThread's context ?

    It can be done with a QThread subclass, but that way is typically frowned upon. If you use as above it is upto you if you wish to use threads or not.

  10. #9
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Receiving slots in QThread's context ?

    Quote Originally Posted by The Storm View Post
    I just wonder why it can't be done with my QThread subclass.
    The conecpt of QThread is not easy to understand by a lot of people, especially because the official documentation of QThread is not sufficient or even correct.
    During the lifetime of Qt4 QThread changed, but the documentation remained the same.

    Why do signals and slots in a QThread subclass not work as expected?
    The only code that runs in a thread other than the main thread is the code that is written in the run() function, or that is being called from the run() function.

    However, you define signal and slot functions in the QThread subclass. If you create a QThread object in your program, this QThread object lives in the main thread. Therefor the signals and slots are also define in the main thread.

    Like I said above, when you call a function of QThread or a subclass from within the run() function, it will also be performed in the new thread. No problem for signals.
    Slots are much more complicated.

    If for example you connect a slot in your QThread subclass in the constructor of your QThread subclass, this slot will be called in the main thread!

    Some people use moveToThread from within their QThread subclass. Although this SEEMS to work, it is wrong. You want to have the QThread object live in your main thread.
    Therefor it is suggested to create a QObject subclass, implement it like any other object. Then create a new QThread object and move the QObject object to the new QThread object. In the background, the whole QObject object is moved to a new thread, instantly executing the slots inside the new thread.

    I guess you can compare it like this:
    Qt Code:
    1. class MyThread: public QThread
    2. {
    3. ...
    4. //slots
    5. //signals
    6. ...
    7. };
    To copy to clipboard, switch view to plain text mode 

    to
    Qt Code:
    1. class MyObjectThread : public
    2. {
    3. public:
    4. void run();
    5. };
    6.  
    7. void MyObjectThread::run()
    8. {
    9. MyObject *obj = new MyObject;
    10.  
    11. connect(..., SIGNAL, obj, SLOT);
    12. }
    To copy to clipboard, switch view to plain text mode 

    Since the object is created in the run() function, it completely lives in the new thread.

  11. The following user says thank you to tbscope for this useful post:

    The Storm (14th August 2010)

  12. #10
    Join Date
    Aug 2007
    Posts
    166
    Thanks
    16
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Receiving slots in QThread's context ?

    Yes you have a point. Thanks for the help.

    EDIT: I just missed your last post tbscope. The things you explained give me much more light on this Qt specific "things". I hope that they will soon fix up the documentation with some nice examples in order to not get more confused users like me.
    Last edited by The Storm; 14th August 2010 at 12:50.

  13. #11
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Receiving slots in QThread's context ?

    Just a disclaimer: This is how I understand it. But I might have posted mistakes in my explanation too.

Similar Threads

  1. Problem with Signal and Slots and QThread
    By Informatix in forum Newbie
    Replies: 2
    Last Post: 7th June 2010, 14:21
  2. QThread signal and slots problem
    By mero in forum Qt Programming
    Replies: 8
    Last Post: 8th May 2010, 01:56
  3. Any examples of receiving slots in threads?
    By draftpunk in forum Qt Programming
    Replies: 2
    Last Post: 9th January 2010, 19:21
  4. QTableWidget, QThread, signals and slots
    By kazek3018 in forum Newbie
    Replies: 4
    Last Post: 30th December 2008, 21:21
  5. QThread communication without signal and slots
    By forrestfsu in forum Qt Programming
    Replies: 16
    Last Post: 22nd May 2007, 00:43

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.