Results 1 to 5 of 5

Thread: Problem with getting QFuture and QFutureWatcher working properly

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2013
    Posts
    3
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X

    Default Problem with getting QFuture and QFutureWatcher working properly

    Hey all,

    I'd like to ask for a little help as I followed some quick tutorials on how to get another thread in my app working. The thing I'm doing is a kind of organiser with calendar that has ability to popup reminders for the user and I'd like to use different thread for checking if there isn't any task to remind the user of and if there is show a popup with info about it. I figured a way to do it from some websites and this is what I've come up with, but unfortunately app is not responding when I try to run it:


    Qt Code:
    1. QFuture<Task*> future = QtConcurrent::run(this, &MainWindow::checkReminders);
    2.  
    3. popupTask = future.result();
    4.  
    5. QFutureWatcher<Task*> watcher;
    6. watcher.setFuture(future);
    7.  
    8. connect(&watcher, SIGNAL(finished()), this, SLOT(popupReminder()));
    To copy to clipboard, switch view to plain text mode 

    Above is set in MainWindow constructor.

    I haven't already connected the popupTask variable to popupReminder() method, because I wanted to make it work first before providing the popup with the information to show.

    Here is MainWindow::checkReminders() method:

    Qt Code:
    1. Task* MainWindow::checkReminders() {
    2. do {
    3. for(int i = 0; i < daysList.count(); i++) {
    4. for(int j = 0; j < daysList[i].getListCount(); j++) {
    5. QDateTime current = QDateTime::currentDateTime();
    6. if(current == *daysList[i].getTaskAtIndex(j)->getReminderTime() &&
    7. !daysList[i].getTaskAtIndex(j)->ifDone() &&
    8. daysList[i].getTaskAtIndex(j)->ifNeededReminder()) {
    9. daysList[i].getTaskAtIndex(j)->turnOffReminder();
    10. return daysList[i].getTaskAtIndex(j);
    11.  
    12. }
    13. }
    14. }
    15. } while (true);
    16.  
    17. }
    To copy to clipboard, switch view to plain text mode 

    and finally the popupReminder() method:

    Qt Code:
    1. void MainWindow::popupReminder() {
    2. QMessageBox::StandardButton reply;
    3. reply = QMessageBox::information(this, tr("QMessageBox::information()"), MESSAGE1);
    4. }
    To copy to clipboard, switch view to plain text mode 

    Earlier I used checkReminders as a void method that just made the window pop up itself, but I've read somewhere that it is better not to make multiple threads take care of GUI, so I thought I'll give it a try with QFutureWatcher. If someone could point out what I'm doing wrong I'd be grateful.
    Last edited by jahsiotr; 13th January 2013 at 12:36.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Problem with getting QFuture and QFutureWatcher working properly

    To be honest you are doing a couple of things wrong. One thing is definitely that you're not protecting your "daysList" data structure from concurrent access from multiple threads. Another is that your loop can potentially run forever (actively) if it fails to find a task that needs to be returned. Third of all is that your search is very inefficient. It's much more efficient to have a queue of tasks sorted by the reminder time. Then all you need to do is check once a minute the first item in the queue whether its time has come or not. Or even set the timer to alarm you when the first item in the queue becomes active. Of course then you need to reset the timer if anything in the queue changes. There is no need nor any benefit from using threads in this situation. Even without any special treatment you don't need any extra threads -- once a minute go through all the items in daysList and check whether any of them need reminding. Assuming you have 10-ish or even 100-ish items in the list, it should be fast enough to not stall your UI.

    Finally your last problem (which is the only one related to the future itself) is that you start a task and immediately ask for its result. If the result is not ready yet, the calling thread will be blocked until the result becomes available. Thus your watcher is never used. If you remove line #3 from your code, the program will start working.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. The following user says thank you to wysota for this useful post:

    jahsiotr (14th January 2013)

  4. #3
    Join Date
    Jan 2013
    Posts
    3
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X

    Default Re: Problem with getting QFuture and QFutureWatcher working properly

    That is a bunch of good advice. Thanks for that. How can I use some method every minute though and not hold up the rest of app by waiting for the timer to indicate that full minute has passed?

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Problem with getting QFuture and QFutureWatcher working properly

    Use QTimer.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. The following user says thank you to wysota for this useful post:

    jahsiotr (14th January 2013)

  7. #5
    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

    There is an additional problem in the original code: the future watcher object is created on the stack, so it is being deleted whenever that function's context ends.
    If I read this correctly this is code inside the main window's constructor, so the future watcher will be gone by the time the window shows up.

    Cheers,
    _

Similar Threads

  1. Replies: 1
    Last Post: 7th December 2011, 00:49
  2. QFutureWatcher finished() signal not working
    By DiamonDogX in forum Qt Programming
    Replies: 13
    Last Post: 25th October 2011, 18:27
  3. QFutureWatcher finished without even starting a QFuture...
    By Zweistein in forum Qt Programming
    Replies: 0
    Last Post: 22nd September 2011, 14:30
  4. memcpy not working properly
    By sattu in forum Qt Programming
    Replies: 3
    Last Post: 26th October 2010, 23:33
  5. ScrollZoomer not working properly..
    By Raghaw in forum Qwt
    Replies: 1
    Last Post: 30th October 2009, 06:51

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
  •  
Qt is a trademark of The Qt Company.