Page 1 of 3 123 LastLast
Results 1 to 20 of 52

Thread: Qt multithreading and let the second thread update the main (UI) thread

  1. #1
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Qt multithreading and let the second thread update the main (UI) thread

    So I have a view (say QFrame) in the main thread (currently there is only a single thread where the entire application resides), where I need to show some query results when the user enters some query term in the text box and presses Enter. This is how it works, I have class called QueryFinder which I instantiate with the query term. Then I call execute(), which polls some internal database for some time to get query results. While instantiating QueryFinder, I also pass the view (the QFrame from which the user queried) and that is held as a view object in the QueryFinder class. Whenever any query result match is found, I call something like fView->updateView(searchResult), and the view has the appropriate method update to show the result. The results keep on coming until the database polling is complete.

    Now the database polling is pretty memory intensive, so while the querying goes on, the UI becomes kind of unresponsive. A loading gif image, for example, which signifies the ongoing querying, often stalls and freezes. So I want to separate out the entire querying part into a separate thread, and that thread should poll, and update the view (which is in a separate thread, the main one). How do I do this in Qt/C++? Here is my pseudocode:

    Qt Code:
    1. //view code
    2. //after user presses enter
    3. if (!finder)
    4. {
    5. finder->stop();
    6. }
    7. finder = new QueryFinder(this, queryTerm);
    8. finder->execute();
    9.  
    10. void updateView(QueryResult &result)
    11. {
    12. //display the query result properly
    13. }
    14.  
    15. //QueryFinder code, header file
    16. class QueryFinder: public QObject
    17. {
    18. public:
    19. QUeryFinder(QWidget *, QueryTerm&);
    20. void execute();
    21. void stop();
    22.  
    23. private:
    24. bool shouldStop;
    25. QWidget *fView;
    26. QueryTerm fTerm;
    27. }
    28.  
    29.  
    30. //QueryFinder code, implementation file
    31. QueryFinder::QueryFinder(QWidget *w, QueryTerm& term): fView(w), fTerm(term)
    32. {
    33. shouldStop = false;
    34. }
    35.  
    36. void QueryFinder::execute()
    37. {
    38. //do the polling and if any result found, say newResult, update view, but only if no new query request has come in
    39. //the meantime, else abnson this object altogether
    40. while (cursor->hasNext()) {
    41. newResult = cursor->getCurResult();
    42. if (!shouldStop)
    43. fView->updateView(newResult);
    44. else
    45. return;
    46. }
    47. }
    48.  
    49. void QueryFinder::stop()
    50. {
    51. shouldStop = true;
    52. }
    To copy to clipboard, switch view to plain text mode 

    If you observe, not only the updating the view, even the stop method needs to go from one thread to another. How do I accomplish this? I have never done any multithreading in Qt/C++.
    Last edited by Cupidvogel; 18th April 2015 at 01:33.

  2. #2
    Join Date
    Nov 2014
    Posts
    35
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Yes, if your task takes a long time and you don't want to freeze the UI thread you need a second worker thread to do the job, and you need to implement the communication between these two threads using signals and slots.

    This article will give you an excellent introduction with examples to QThread:

    http://blog.debao.me/2013/08/how-to-...ht-way-part-1/
    pixaeiro
    http://www.pixaflux.com
    Non-destructive Image Editor

  3. #3
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Yes, I have studied it, but it gives very simplistic examples, I have almost zero idea how to implement it here.

  4. #4
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    My personal preference is to use the "move to thread" method, which is described here:

    https://mayaposch.wordpress.com/2011...l-explanation/

    Design your worker object the like a normal class that inherits QObject, add signals/slots necessary to communicate with your main GUI thread, etc. Qt will automatically do the right thing if you connect signals/slots across different threads. Qt::QueuedConnection is used if the sender and receiver are in different threads.

  5. #5
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Can you provide some pseudo code to show how to at least structure it? I am feeling totally lost..

  6. #6
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    The example I referred you to had example code, no?

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

    Cupidvogel (18th April 2015)

  8. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Well, you just have to make updateView() a slot and add a matching signal to the QueryFinder class and connect the two.
    Then, instead of calling the view directly, you just emit the signal.

    Cheers,
    _

  9. #8
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Okay, I got that part. Here two thread communicate via signals and slots. But in this case, the slot must receive an object of type QueryResult. Qt greatly limits how signals and slots can use parameters, and the one way I can see, is to use a Signal Mapper. But even with Signal Mapper, I don't know how to properly use it to say, emit a signal from one object with a QString as param, and capture and use the sent QString in a slot in another object. I browsed net heavily, I could not find a complete working example of it. Secondly, even Signal Mapper allows only certain basic types of params to be exchanged, like QString. Here the object which is required to update the view is of a custom class, QueryResult. How will the Action class and the View class communicate?

    Quote Originally Posted by jefftee View Post
    The example I referred you to had example code, no?

    Again, this was a pretty basic example. Which class here should inherit from QThread? I couldn't see any threading in your example at all..
    Last edited by Cupidvogel; 18th April 2015 at 12:41.

  10. #9
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Quote Originally Posted by Cupidvogel View Post
    But in this case, the slot must receive an object of type QueryResult.
    Yes, I should have written updateView(const QueryResult&), but I thought it would be pretty obvious that the signal would need to transport the data as its argument.

    Quote Originally Posted by Cupidvogel View Post
    Qt greatly limits how signals and slots can use parameters
    In what way?

    Quote Originally Posted by Cupidvogel View Post
    and the one way I can see, is to use a Signal Mapper
    Why on earth would you need a signal mapper?

    Quote Originally Posted by Cupidvogel View Post
    But even with Signal Mapper, I don't know how to properly use it to say, emit a signal from one object with a QString as param, and capture and use the sent QString in a slot in another object.
    You would not use a signal mapper when you can use a trivial signal/slot connection between two objects.

    Quote Originally Posted by Cupidvogel View Post
    I browsed net heavily, I could not find a complete working example of it.
    Heavly for how many seconds?
    The first Google hit on signal/slots is the Qt documentation on that topic (which should be the primary source even without search engine help) and it does naturally have an example that transports a value through the connection.

    Quote Originally Posted by Cupidvogel View Post
    Which class here should inherit from QThread?
    The suggestion was to use moveToThread() of the worker object which does not require subclassing QThread.

    Cheers,
    _

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

    Cupidvogel (18th April 2015)

  12. #10
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Can you give an example of how without using signal mapper I can transport a parameter, say, an object belonging to a custom class?

    Which object do I need to move to thread? My Query Action class?

  13. #11
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Quote Originally Posted by Cupidvogel View Post
    Can you give an example of how without using signal mapper I can transport a parameter, say, an object belonging to a custom class?
    What is it with you and the signal mapper? There is no indication of any need for a signal mapper.
    Declare a signal with the respective type as its argument type.

    Quote Originally Posted by Cupidvogel View Post
    Which object do I need to move to thread? My Query Action class?
    Well, the object that you want to run in the other thread.
    Probably the instance of your QueryFinder class.

    Cheers,
    _

  14. The following user says thank you to anda_skoa for this useful post:

    Cupidvogel (18th April 2015)

  15. #12
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Quote Originally Posted by Cupidvogel View Post
    Can you give an example of how without using signal mapper I can transport a parameter, say, an object belonging to a custom class?

    Which object do I need to move to thread? My Query Action class?
    Look at the Q_DECLARE_METATYPE macro, which you can used to declare any custom types and the qRegisterMetaType macro. These two macros are needed to register a custom metatype that can be used for signal/slot parameters.

    The class you moveToThread is the one that has the signals/slots and code that you wish to execute in a separate thread.


    Added after 6 minutes:


    Quote Originally Posted by Cupidvogel View Post
    Qt greatly limits how signals and slots can use parameters, and the one way I can see, is to use a Signal Mapper.
    That is a wildly inaccurate statement. Qt supports all native types, many Qt types, and allows you to register any custom type to the meta object system. How can you say that Qt greatly limits the use of parameters?
    Last edited by jefftee; 18th April 2015 at 17:43.

  16. The following user says thank you to jefftee for this useful post:

    Cupidvogel (18th April 2015)

  17. #13
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Quote Originally Posted by jefftee View Post
    Look at the Q_DECLARE_METATYPE macro, which you can used to declare any custom types and the qRegisterMetaType macro. These two macros are needed to register a custom metatype that can be used for signal/slot parameters.
    Just as a clarification: only because this is a cross-thread signal/slot connection (Qt::QueuedConnection).
    A direct connection does not require any thing from the argument types.

    Cheers,
    _

  18. The following user says thank you to anda_skoa for this useful post:

    Cupidvogel (18th April 2015)

  19. #14
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Quote Originally Posted by anda_skoa View Post
    Just as a clarification: only because this is a cross-thread signal/slot connection (Qt::QueuedConnection).
    A direct connection does not require any thing from the argument types.
    Thanks for clarifying. I will usually register my custom types whether or not I am using threads and cross-thread signals/slots. I believe the other beneficial reason to do so is that you can use QVariant for custom types that have been registered, which may come in handy too.

  20. The following user says thank you to jefftee for this useful post:

    Cupidvogel (18th April 2015)

  21. #15
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Okay. First of all, I am very sorry about my statement about signals and slots. I experimented with them, and I can see that they jolly well accept all sorts of parameters, be standard types or custom objects. Sorry about that.

    As for the subject of this thread, I tried the example 2.1 of this article: http://blog.debao.me/2013/08/how-to-...ht-way-part-1/

    I created a separate WorkerThread class like this:

    Qt Code:
    1. //header: WorkerThread.hpp
    2.  
    3. #include <QObject>
    4. #include <QThread>
    5. #include <QDebug>
    6.  
    7. class WorkerThread : public QObject
    8. {
    9. Q_OBJECT
    10.  
    11. public:
    12. WorkerThread();
    13.  
    14. private slots:
    15. void onTimeout()
    16. {
    17. qDebug() << "Worker::onTimeout get called from?: "<< QThread::currentThreadId();
    18. }
    19. };
    20.  
    21.  
    22. //implementation: WorkerThread.cpp
    23.  
    24. #include "WorkerThread.hpp"
    25.  
    26. WorkerThread::WorkerThread()
    27. {
    28. }
    To copy to clipboard, switch view to plain text mode 

    Then in my View class, where I instantiate the action and call its execute method to start the database polling, I added the timer part:

    Qt Code:
    1. //view class
    2.  
    3. connect(queryButton, SIGNAL(clicked()), this, SLOT(doQuery()));
    4.  
    5. void QueryView::doQuery()
    6. {
    7. /*---------------previous code
    8.   if (!finder)
    9. {
    10. finder->stop();
    11. }
    12. finder = new QueryFinder(this, queryTerm);
    13. finder->execute();
    14. -----------------*/
    15.  
    16. //new code:
    17.  
    18. qDebug() << "From main thread: " << QThread::currentThreadId();
    19.  
    20. QTimer timer;
    21. WorkerThread worker;
    22.  
    23. QObject::connect(&timer, SIGNAL(timeout()), &worker, SLOT(onTimeout()));
    24. timer.start(1000);
    25.  
    26. timer.moveToThread(&t);
    27. worker.moveToThread(&t);
    28.  
    29. t.start();
    30. }
    To copy to clipboard, switch view to plain text mode 

    Now when I click the button, contrary to what is given as output in the example, I get this output:

    Qt Code:
    1. From main thread: 0xa06771d4
    2. QThread: Destroyed while thread is still running
    3. The program has unexpectedly finished.
    To copy to clipboard, switch view to plain text mode 

    followed by the app crashing. The Apple system generated crash report shows this message:

    Qt Code:
    1. Thread 0:: Dispatch queue: com.apple.main-thread
    2. 0 libsystem_kernel.dylib 0x9a4709cf mach_absolute_time + 1
    3. 1 com.apple.HIToolbox 0x9bef7957 GetCurrentEventTime + 18
    4. 2 com.apple.HIToolbox 0x9beee570 ReceiveNextEventCommon + 301
    5. 3 com.apple.HIToolbox 0x9beee42c _BlockUntilNextEventMatchingListInModeWithFilter + 99
    6. 4 com.apple.AppKit 0x95da7721 _DPSNextEvent + 742
    7. 5 com.apple.AppKit 0x95da6dc5 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 350
    8. 6 com.apple.AppKit 0x95d9b77c -[NSApplication run] + 907
    9. 7 libqcocoa.dylib 0x05878bf1 0x5858000 + 134129
    10. 8 QtCore 0x02d85181 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 401
    11. 9 QtCore 0x02d881ed QCoreApplication::exec() + 349
    12. 10 com.<product_id>.<project> 0x000a2d08 main + 344
    13. 11 com.<product_id>.<project> 0x000a1c15 start + 53
    14.  
    15. Thread 1:: Dispatch queue: com.apple.libdispatch-manager
    16. 0 libsystem_kernel.dylib 0x9a4788ce kevent64 + 10
    17. 1 libdispatch.dylib 0x953a673f _dispatch_mgr_invoke + 245
    18. 2 libdispatch.dylib 0x953a63a2 _dispatch_mgr_thread + 52
    19.  
    20. Thread 2:
    21. 0 libsystem_kernel.dylib 0x9a477e6a __workq_kernreturn + 10
    22. 1 libsystem_pthread.dylib 0x904b82b1 _pthread_wqthread + 939
    23. 2 libsystem_pthread.dylib 0x904b5e2e start_wqthread + 30
    24.  
    25. Thread 3:
    26. 0 libsystem_kernel.dylib 0x9a477e6a __workq_kernreturn + 10
    27. 1 libsystem_pthread.dylib 0x904b82b1 _pthread_wqthread + 939
    28. 2 libsystem_pthread.dylib 0x904b5e2e start_wqthread + 30
    29.  
    30. Thread 4:
    31. 0 libsystem_kernel.dylib 0x9a477e6a __workq_kernreturn + 10
    32. 1 libsystem_pthread.dylib 0x904b82b1 _pthread_wqthread + 939
    33. 2 libsystem_pthread.dylib 0x904b5e2e start_wqthread + 30
    34.  
    35. Thread 5:
    36. 0 libsystem_kernel.dylib 0x9a4719ce mach_msg_trap + 10
    37. 1 libsystem_kernel.dylib 0x9a470a70 mach_msg + 68
    38. 2 com.apple.CoreFoundation 0x9321bef6 __CFRunLoopServiceMachPort + 214
    39. 3 com.apple.CoreFoundation 0x9321b309 __CFRunLoopRun + 1529
    40. 4 com.apple.CoreFoundation 0x9321aaa6 CFRunLoopRunSpecific + 390
    41. 5 com.apple.CoreFoundation 0x9321a90b CFRunLoopRunInMode + 123
    42. 6 com.apple.AppKit 0x95e76ea0 _NSEventThread + 283
    43. 7 libsystem_pthread.dylib 0x904b7e13 _pthread_body + 138
    44. 8 libsystem_pthread.dylib 0x904b7d89 _pthread_start + 162
    45. 9 libsystem_pthread.dylib 0x904b5e52 thread_start + 34
    46.  
    47. Thread 6:: Qt bearer thread
    48. 0 libsystem_kernel.dylib 0x9a47784e __select + 10
    49. 1 QtCore 0x02dd9732 qt_safe_select(int, fd_set*, fd_set*, fd_set*, timespec const*) + 546
    50. 2 QtCore 0x02dda6ef QEventDispatcherUNIXPrivate::doSelect(QFlags<QEventLoop::ProcessEventsFlag>, timespec*) + 975
    51. 3 QtCore 0x02ddb89d QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 269
    52. 4 QtCore 0x02d85181 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 401
    53. 5 QtCore 0x02b9ab7c QThread::exec() + 108
    54. 6 QtCore 0x02b9e66c QThreadStorageData::finish(void**) + 3020
    55. 7 libsystem_pthread.dylib 0x904b7e13 _pthread_body + 138
    56. 8 libsystem_pthread.dylib 0x904b7d89 _pthread_start + 162
    57. 9 libsystem_pthread.dylib 0x904b5e52 thread_start + 34
    58.  
    59. Thread 7:: QProcessManager
    60. 0 libsystem_kernel.dylib 0x9a47784e __select + 10
    61. 1 QtCore 0x02d2677d QLockFile::unlock() + 2397
    62. 2 QtCore 0x02b9e66c QThreadStorageData::finish(void**) + 3020
    63. 3 libsystem_pthread.dylib 0x904b7e13 _pthread_body + 138
    64. 4 libsystem_pthread.dylib 0x904b7d89 _pthread_start + 162
    65. 5 libsystem_pthread.dylib 0x904b5e52 thread_start + 34
    66.  
    67. Thread 8:: com.apple.CFSocket.private
    68. 0 libsystem_kernel.dylib 0x9a47784e __select + 10
    69. 1 com.apple.CoreFoundation 0x9326bb3a __CFSocketManager + 906
    70. 2 libsystem_pthread.dylib 0x904b7e13 _pthread_body + 138
    71. 3 libsystem_pthread.dylib 0x904b7d89 _pthread_start + 162
    72. 4 libsystem_pthread.dylib 0x904b5e52 thread_start + 34
    To copy to clipboard, switch view to plain text mode 

    What am I doing wrong?

  22. #16
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Quote Originally Posted by Cupidvogel View Post
    What am I doing wrong?
    For starters, your QThread instance t will be destroyed right after you do the t.start() because it's allocated on the stack and will go out of scope as sooon as doQuery() returns. Allocate it on the heap (new QThread()) and save a pointer to it for future use or make it a class member variable.

    Same for your timer and worker object. Make them member variables or allocate from the heap, etc.

    Edit: Not sure why you are trying to move the timer to the thread too. In my experience I have only moved the worker object to the QThread. I would also recommend that you rename your WorkerThread class to WorkerObject as it is misleading to name it as a thread.
    Last edited by jefftee; 18th April 2015 at 22:58.

  23. The following user says thank you to jefftee for this useful post:

    Cupidvogel (18th April 2015)

  24. #17
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Cool. That worked. Yes, no need to move the timer, they just gave it by way of an example, in the example following it, they commented that line out.. So along these footsteps, is this design correct for my code? Will this be enough, or am I doing something wrong?

    Qt Code:
    1. //inside the slot
    2.  
    3. //get the query term, and pass it to the action, it will update view through signal/slot, so longer need to pass view as param
    4.  
    5. std::shared_ptr<QueryAction> action = std::make_shared<QueryAction>(queryTerm);
    6.  
    7. //this in turn will run a while loop polling the database, and finish gracefully once polling is complete
    8. action->execute();
    9.  
    10. QThread *t = new QThread();
    11. action->moveToThread(t);
    To copy to clipboard, switch view to plain text mode 

  25. #18
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Quote Originally Posted by jefftee View Post
    Thanks for clarifying. I will usually register my custom types whether or not I am using threads and cross-thread signals/slots. I believe the other beneficial reason to do so is that you can use QVariant for custom types that have been registered, which may come in handy too.
    Right, Q_DECLARE_METATYPE is required for encapsulating the type in QVariant. qRegisterMetaType() is needed, if the QVariant needs to be created without calling fromValue().
    Which is the case of a signal/slot connection using Qt::QueuedConnection (such as a cross-thread one).

    Cheers,
    _

  26. #19
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    Quote Originally Posted by Cupidvogel View Post
    Qt Code:
    1. //inside the slot
    2.  
    3. //get the query term, and pass it to the action, it will update view through signal/slot, so longer need to pass view as param
    4.  
    5. std::shared_ptr<QueryAction> action = std::make_shared<QueryAction>(queryTerm);
    6.  
    7. //this in turn will run a while loop polling the database, and finish gracefully once polling is complete
    8. action->execute();
    9.  
    10. QThread *t = new QThread();
    11. action->moveToThread(t);
    To copy to clipboard, switch view to plain text mode 
    Not sure what action->execute() is intended to do in line 8. If your intent is to execute something in the new thread, that's not the correct way to accomplish that. For starters, you haven't created the new QThread yet, nor has it been started (QThread::start). Typically you would emit a signal that is connected to a slot in your Worker object, which can be easily done with a QTimer::singleShot.

    The pointer on line 10 is a local pointer, so you will lose the ability to address your QThread after your slot returns. Make the pointer a class member variable, which will allow you to use it later on.

    You should also make all of your signal/slot connections for the Worker object and QThread after line 11.

    Lastly, after you have created the QThread, moved your Worker object to the QThread, and made your signal/slot connections, you need to start the QThread so that it begins running its event loop.

    After you have done all of that, then QTimer::singleShot with a 0ms wait to queue the signal to execute in the new thread, etc.

    Once you have all of that working, you should add a boolean to your Worker object that you can use to tell it to stop processing. i.e. You have started doing a long running task in the new thread and the user wants to cancel the task or close the program, etc. Your long running task would then check the boolean to determine if stop has been requested, etc. To make it all thread safe, you should protect the boolean member variable with a QMutex and QMutexLocker whenever you read or change the boolean value.

    Hope that helps.

  27. The following user says thank you to jefftee for this useful post:

    Cupidvogel (18th April 2015)

  28. #20
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Qt multithreading and let the second thread update the main (UI) thread

    I don't understand, why do we need a timer here? I though that was an example just for explaining how multi threading works in Qt?

Similar Threads

  1. Replies: 1
    Last Post: 28th March 2012, 19:58
  2. Replies: 5
    Last Post: 22nd February 2011, 22:21
  3. Replies: 9
    Last Post: 28th November 2009, 21:31
  4. Replies: 16
    Last Post: 7th October 2009, 09:17
  5. Replies: 6
    Last Post: 29th April 2009, 19:17

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.