Page 2 of 3 FirstFirst 123 LastLast
Results 21 to 40 of 52

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

  1. #21
    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

    Use a QTimer or don't use a QTimer, doesn't matter to me...

  2. #22
    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. So here is my revised code. Is this okay?

    QueryView.hpp:

    Qt Code:
    To copy to clipboard, switch view to plain text mode 

    QueryView.cpp:

    Qt Code:
    1. QueryView::QueryView()
    2. {
    3. connect(SignalClass.get(),SIGNAL(updateViewSignal(QueryTerm&)), this, SLOT(updateView(QueryTerm&)));
    4. connect(queryButton, SIGNAL(clicked()),this, SLOT(doQuery()));
    5. }
    6.  
    7. void QueryView::doQuery()
    8. {
    9. t = new QThread()
    10. emit fSignalClass->stopExistingQuery();
    11. std::shared_ptr<QueryAction> action = std::make_shared<QueryAction>(queryTerm);
    12. action->moveToThread(t);
    13. t->start();
    14. emit fSignalClass->excuteSignal();
    15.  
    16. }
    17.  
    18. QueryView::updateView(QueryTerm& term)
    19. {
    20. ...update view with query result
    21. }
    To copy to clipboard, switch view to plain text mode 

    QueryAction class:

    Qt Code:
    1. QueryAction::QueryAction(QueryTerm& queryTerm): fQueryTerm(queryTerm)
    2. {
    3. connect(SignalClass.get(), SIGNAL(excuteSignal()), this, SLOT(startSearch()));
    4. connect(SignalClass.get(), SIGNAL(stopExistingQuery()), this, SLOT(stopQuery()));
    5. continueQuery = true;
    6. }
    7.  
    8. void QueryAction::startSearch()
    9. {
    10. //init cursor
    11. while (db_cursor != empty)
    12. {
    13. ...get query result
    14. if (continueQuery)
    15. emit fSignalClass->updateViewSignal(aResult);
    16. }
    17. }
    18.  
    19. void QueryAction::stopQuery()
    20. {
    21. continueQuery = false;
    22. }
    To copy to clipboard, switch view to plain text mode 

  3. #23
    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

    You should protect continueQuery with a QMutex and you should also return from startSearch (or break out of while loop) where you check whether continueQuery is true on line 14.

    Other than that, does it work?

  4. #24
    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, so here is my revised QueryAction class:

    Qt Code:
    1. //QueryAction.hpp:
    2.  
    3. class QueryAction
    4.  
    5. {
    6. QMutex m_mutex;
    7. }
    8.  
    9. //QueryAction.cpp
    10.  
    11. QueryAction::QueryAction(QueryTerm& queryTerm): fQueryTerm(queryTerm)
    12. {
    13. connect(SignalClass.get(), SIGNAL(excuteSignal()), this, SLOT(startSearch()));
    14. connect(SignalClass.get(), SIGNAL(stopExistingQuery()), this, SLOT(stopQuery()));
    15. continueQuery = true;
    16. }
    17.  
    18. void QueryAction::startSearch()
    19. {
    20. //init cursor
    21. while (db_cursor != empty)
    22. {
    23. ...get query result
    24. QMutexLocker locker(&m_mutex);
    25. if (continueQuery)
    26. emit fSignalClass->updateViewSignal(aResult);
    27. else
    28. break;
    29. }
    30. }
    31.  
    32. void QueryAction::stopQuery()
    33. {
    34. QMutexLocker locker(&m_mutex);
    35. continueQuery = false;
    36. }
    To copy to clipboard, switch view to plain text mode 

    Is this correct logic? I haven't tried it yet, for one, this will need a large amount of code change and I am not ready for it now, and secondly, I want to understand it fully before I get my hands dirty, so trying to get my logic right..

  5. #25
    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
    Is this correct logic? I haven't tried it yet, for one, this will need a large amount of code change and I am not ready for it now, and secondly, I want to understand it fully before I get my hands dirty, so trying to get my logic right..
    It looks correct to me, but as much as I enjoy being your compiler and debugger, the only thing that matters is that the code executes correctly, so you need to set breakpoints, step through your code, etc. to ensure it's working the way you want.

  6. #26
    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

    Yep yep, of course. Will do the entire code and get back to you..

  7. #27
    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
    Okay. So here is my revised code. Is this okay?
    Qt Code:
    1. connect(SignalClass.get(),SIGNAL(updateViewSignal(QueryTerm&)), this, SLOT(updateView(QueryTerm&)));
    To copy to clipboard, switch view to plain text mode 
    If this is the cross-thread connection then a reference is not correct (and it would quite uncommon for any type of connection).
    Qt Code:
    1. connect(queryAction, SIGNAL(updateViewSignal(QueryTerm)), this, SLOT(updateView(QueryTerm)));
    To copy to clipboard, switch view to plain text mode 

    Quote Originally Posted by Cupidvogel View Post
    Qt Code:
    1. emit fSignalClass->stopExistingQuery();
    To copy to clipboard, switch view to plain text mode 
    Don't emit another object's signals. This would not even compile in Qt4.

    Quote Originally Posted by Cupidvogel View Post
    Qt Code:
    1. void QueryView::updateView(QueryTerm& term)
    To copy to clipboard, switch view to plain text mode 
    If this is the slot invoked through the cross-thread signal/slot connection then it won't get a reference
    Qt Code:
    1. void QueryView::updateView(const QueryTerm& term)
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

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

    Cupidvogel (19th April 2015)

  9. #28
    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

    Well, emitting other object's signal does work for me. I ma using Qt 5.3.1, and it works fine like this:

    Qt Code:
    1. class SignalClass : public QObject
    2. {
    3. Q_OBJECT
    4. public:
    5. SignalClass(QObject *parent = 0) : QObject(parent)
    6. {
    7. }
    8. signals:
    9. void excuteSignal();
    10. void randomSignal(QString);
    11. }
    To copy to clipboard, switch view to plain text mode 

    And using it like this:

    Qt Code:
    1. //somewhere we emit it
    2. std::shared_ptr< SignalClass > fSignalClass = std::make_shared< SignalClass >();
    3. emit fSignalClass->randomSignal(fString);
    4.  
    5. //and somewhere else connect it to individual slot
    6. connect(SignalClass.get(), SIGNAL(randomSignal(QString)), this, SLOT(captureString()));
    To copy to clipboard, switch view to plain text mode 

    I will remove the references from cross thread signal-slot connections. Cheers!

  10. #29
    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
    Well, emitting other object's signal does work for me. I ma using Qt 5.3.1
    Yes, in Qt5 the access level for signals had to be made "public" (was "proteced" before) in order to make the compile time connect() work.
    Emitting another object's signals is of course still a very bad idea, they used to be protected for a reason.

    Especially in the presence of threads, when QObject thread-affinity matters.

    Cheers,
    _

  11. #30
    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, so what other way can I make it work?

  12. #31
    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
    Okay, so what other way can I make it work?
    I am afraid I don't understand the question.

    What "other way" do you need for which problem?

    Cheers,
    _

  13. #32
    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

    Sorry. What I meant is that what other way can I connect a signal from one object to a slot in another? I mean, I can define a signal in the class that raises it and raise it, and I can define a slot in the receiver object, but how do I connect the two in the receiver object?

  14. #33
    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

    connect() always works the same way:
    Qt Code:
    1. connect(sender, SIGNAL(...), receiver, SLOT(...));
    To copy to clipboard, switch view to plain text mode 
    I.e. the code that runs the connect() needs access to both objects.
    Whether none, one or both of these objects is "this" doesn't matter to connect().

    Cheers,
    _

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

    Cupidvogel (19th April 2015)

  16. #34
    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

    Yeah, that is definitely one way of doing it, but I did not do it because it would introduce cyclic dependency, that is A will include B and B will include A, etc. But I will make it work anyhow. In the mean time, I tried out the entire revised code.

    The query results are coming out correctly, I am applying a qDebug() on them when they are generated and they are printed correctly. But the view is not being updated through the signal/slot. I am getting this debugging message:

    Qt Code:
    1. QObject::connect: Cannot queue arguments of type 'std::shared_ptr<QueryResult>'
    2. (Make sure 'std::shared_ptr< QueryResult >' is registered using qRegisterMetaType().)
    3.  
    4. //this starts coming from the qDebug() statement...
    5. Query result: context of a process and investigates the
    6. Query result: this proved it as because
    To copy to clipboard, switch view to plain text mode 

    How can I make it work?

  17. #35
    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

    Bad news. To temporarily check whether it actually works, instead of passing QueryResult to the slot in the view, I just passed QString and made the view display it as a QPushButton. It is hanging even more than before I multithreaded it. Previously the app was stalling and freezing, but now it is completely hanging, and not being restored until the querying is complete. I verified, the thread ids for the Action thread and main thread are different.

  18. #36
    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
    Yeah, that is definitely one way of doing it, but I did not do it because it would introduce cyclic dependency, that is A will include B and B will include A, etc.
    How does that introduce a dependency of any sort, much less a cyclic one?
    Neither receiver nor sender need to know about each other!

    Quote Originally Posted by Cupidvogel View Post
    Qt Code:
    1. QObject::connect: Cannot queue arguments of type 'std::shared_ptr<QueryResult>'
    2. (Make sure 'std::shared_ptr< QueryResult >' is registered using qRegisterMetaType().)
    To copy to clipboard, switch view to plain text mode 
    Seems like you have an argument type that you did not register with the Qt type system, as explained earlier by jefftee.
    Especially the shared_ptr looks strange given that you should have a "const QueryResult&" as the argument type for both signal and slot.

    So make sure that

    1) your QueryResult class has been marked with Q_DECLARE_METATYPE
    2) your QueryResult class has been registered with qRegisterMetaType()
    3) your signal has a signature with either "QueryResult" or "const QueryResult&" as its argument type
    4) your slot has a matching signature.

    Cheers,
    _

  19. #37
    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

    Quote Originally Posted by anda_skoa View Post
    How does that introduce a dependency of any sort, much less a cyclic one?
    Neither receiver nor sender need to know about each other!
    _
    I have worked around it.

    Quote Originally Posted by anda_skoa View Post
    How does that introduce a dependency of any sort, much less a cyclic one?
    1) your QueryResult class has been marked with Q_DECLARE_METATYPE
    2) your QueryResult class has been registered with qRegisterMetaType()
    _
    How do I do it? I found an example here: http://stackoverflow.com/questions/1...eta-type-in-qt, is this how it will work?

    Qt Code:
    1. class QueryResult
    2. {
    3.  
    4. QString queryString;
    5. QString metadata;
    6. int offset;
    7. }
    8. Q_DECLARE_METATYPE( QueryResult* )
    To copy to clipboard, switch view to plain text mode 

    Where do I call the qRegisterMetaType() method on QueryTerm then? And okay, I will change the signature to const QueryAction& instead of std::shared_ptr<QueryAction>.

  20. #38
    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
    Where do I call the qRegisterMetaType() method on QueryTerm then? And okay, I will change the signature to const QueryAction& instead of std::shared_ptr<QueryAction>.
    You can register the meta type at any time, but obviously must be done before you attempt to use it... I typically do that early in the constructor for the main widget.

  21. #39
    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 wil try to do it. But in the mean time, performance has not only not improved, it has badly worsened. I am just passing in a dummy QString to the view instead of the QueryAction object to check whether it actually works..

  22. #40
    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

    Post your code again please. I have lost track of where your overall code base has morphed since the many posts to this thread have been made. Also, please elaborate on what performance badly worsened means.

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.