Results 1 to 14 of 14

Thread: QThread slot executed in GUI thread

  1. #1
    Join Date
    May 2010
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QThread slot executed in GUI thread

    Hi,

    I've got a GUI application (QApplication) that has a QMainWindow as the GUI. In this I have a button that triggers an action that should be executed in a thread. To achieve this I connect the buttons clicked() signal to a slot in the thread object. However the threads action is executed in the GUI thread.

    Problem can be seen with the code below. On (at least) the second click on the button in the GUI I want the GUI to remain responsive and the thread to sleep.

    Does anyone have an idea as to what I am doing wrong?

    main.cpp
    Qt Code:
    1. #include <QtGui/QApplication>
    2. #include <QDebug>
    3. #include "mainwindow.h"
    4.  
    5. int main(int argc, char *argv[])
    6. {
    7. QApplication a(argc, argv);
    8. MainWindow w;
    9. w.show();
    10. qDebug() << "main:" << a.thread();
    11. return a.exec();
    12. }
    To copy to clipboard, switch view to plain text mode 

    thread.h
    Qt Code:
    1. #ifndef THREAD_H
    2. #define THREAD_H
    3.  
    4. #include <QThread>
    5.  
    6. class Thread : public QThread
    7. {
    8. Q_OBJECT
    9. public:
    10. explicit Thread(QObject *parent = 0);
    11. void run();
    12.  
    13. signals:
    14. void WorkDone();
    15.  
    16. public slots:
    17. void DoWork();
    18. };
    19.  
    20. #endif // THREAD_H
    To copy to clipboard, switch view to plain text mode 

    thread.cpp
    Qt Code:
    1. #include "thread.h"
    2.  
    3. #include <QDebug>
    4.  
    5. Thread::Thread(QObject *parent) :
    6. QThread(parent)
    7. {
    8. qDebug() << "Creating new Thread" << QThread::currentThreadId();
    9. }
    10.  
    11. void Thread::run()
    12. {
    13. qDebug() << "run:" << QThread::currentThreadId();
    14. exec();
    15. }
    16.  
    17. void Thread::DoWork()
    18. {
    19. qDebug() << "Thread::DoWork() in thread:" << QThread::currentThreadId();
    20. sleep(10);
    21. }
    To copy to clipboard, switch view to plain text mode 

    mainwindow.h
    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include "thread.h"
    5.  
    6. #include <QMainWindow>
    7.  
    8. class MainWindow : public QMainWindow
    9. {
    10. Q_OBJECT
    11.  
    12. public:
    13. explicit MainWindow(QWidget *parent = 0);
    14. ~MainWindow();
    15.  
    16. private:
    17. Thread thread;
    18. };
    19.  
    20. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    mainwindow.cpp
    Qt Code:
    1. #include "mainwindow.h"
    2.  
    3. #include <QtGui>
    4. #include <QDebug>
    5.  
    6. MainWindow::MainWindow(QWidget *parent) :
    7. QMainWindow(parent)
    8. {
    9. qDebug() << "MainWindow:" << this;
    10. QWidget *widget = new QWidget();
    11. QHBoxLayout *layout = new QHBoxLayout(widget);
    12. QPushButton *button = new QPushButton("Do work...", widget);
    13. widget->setLayout(layout);
    14. layout->addWidget(button);
    15. setCentralWidget(widget);
    16. thread.start();
    17. connect(button, SIGNAL(clicked()), &thread, SLOT(DoWork()));
    18. }
    19.  
    20. MainWindow::~MainWindow()
    21. {
    22. thread.exit();
    23. thread.wait();
    24. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by tnyblom; 24th May 2010 at 11:26.

  2. #2
    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: QThread slot executed in GUI thread

    You never start another thread.

    Implement QThread::run() in your own thread.
    Then use QThread::start() to start your thread.

    http://doc.qt.nokia.com/4.6/threads-starting.html

  3. #3
    Join Date
    May 2010
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread slot executed in GUI thread

    Sorry that was my mistake, please see the post again (I've updated it), but the problem persists.

  4. #4
    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: QThread slot executed in GUI thread

    Now you have actually started a new thread and executed the run() function once.
    If you call DoWork(), the thread doesn't actually execute what is in the run() function.

    Try calling run() from within your DoWork() function.

  5. #5
    Join Date
    May 2010
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread slot executed in GUI thread

    But I do not wan't to execute the run function I wan't to execute something else (exec() in run is due to the use of QEvents).

    If I call run() from DoWork() will that not create problems since Thread will have multiple invocations of run() running at the same time? How will this affect Event handling?

  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: QThread slot executed in GUI thread

    Quote Originally Posted by tnyblom View Post
    But I do not wan't to execute the run function I wan't to execute something else (exec() in run is due to the use of QEvents).
    I suggest you read more about threading in Qt. There's a lot of information on the documentation website.

    If I call run() from DoWork() will that not create problems since Thread will have multiple invocations of run() running at the same time? How will this affect Event handling?
    Well duh! :-)
    Threading in general isn't very easy :-)

    The run() function contains the code that is actually being executed by your thread.
    In most cases, an infinite loop is created in the run function. Then mutexes and waitconditions are used to queue the requests for the thread.
    See the examples.

  7. #7
    Join Date
    Apr 2010
    Location
    Rostov-na-Donu, Russia
    Posts
    153
    Thanks
    2
    Thanked 26 Times in 23 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread slot executed in GUI thread

    add this code in run() function
    Qt Code:
    1. moveToThread( this );
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    May 2010
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread slot executed in GUI thread

    Thanks for the effort to all, but nothing does what I want.

    I need/want to issue a signal in one thread and get another to pickup the slot. Is this possible?
    So far all my attempts have resulted in the slot being run in the same thread that sent the signal but in the context of the slot object.

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

    Default Re: QThread slot executed in GUI thread

    As already explained, 'moveToThread' will move the event handling from the thread that sent the signal to the thread where the slot is.

    (Assuming you actually run an event loop in the new thread of course)

  10. #10
    Join Date
    May 2010
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread slot executed in GUI thread

    Well not here (at least not as I understand it)

    If I use moveToThread() in run() I get an error
    "QObject::moveToThread: Current thread (0x12fecc) is not the object's thread (0xd47550).
    Cannot move to target thread (0x12fecc) "

    and if I use moveToThread() in my slot I get an ASSERT in qglobal.cpp:2233 "Cannot send events to objects owned by a different thread".

  11. #11
    Join Date
    May 2010
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread slot executed in GUI thread

    Found the root cause:
    (hint from: http://huntharo.com/huntharo/Blog/En...in_thread.html)

    I need to call moveToThread() in the Thread ctor after calling start().

  12. #12
    Join Date
    Apr 2010
    Location
    Rostov-na-Donu, Russia
    Posts
    153
    Thanks
    2
    Thanked 26 Times in 23 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QThread slot executed in GUI thread

    tnyblom, sorry, you must call moveToThread(this) in thread's constructor

  13. #13
    Join Date
    May 2010
    Posts
    7
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread slot executed in GUI thread

    And that was what I wrote.

    More specifically I need to call moveToThread() in the context of the thread that created the thread, and supply the threads thread object as the param.
    Last edited by tnyblom; 25th May 2010 at 08:14.

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

    Default Re: QThread slot executed in GUI thread

    Quote Originally Posted by tnyblom View Post
    More specifically I need to call moveToThread() in the context of the thread that created the thread, and supply the threads thread object as the param.
    Which you can easily forget to do, which is why it's much easier to just use moveToThread(this) in the threads constructor, then it's guaranteed to be called in the context of the thread that created the thread, even if you create multiple copies from different parts of your code.

Similar Threads

  1. How can I get the thread ID out of QThread
    By Artschi in forum Qt Programming
    Replies: 9
    Last Post: 8th November 2017, 04:27
  2. Replies: 9
    Last Post: 28th November 2009, 21:31
  3. Replies: 1
    Last Post: 11th September 2008, 21:45
  4. Replies: 4
    Last Post: 26th June 2008, 19:41
  5. QThread, QMessageBox, gui thread
    By TheKedge in forum Qt Programming
    Replies: 1
    Last Post: 25th October 2006, 13:23

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.