Results 1 to 3 of 3

Thread: QMessageBox in slot signaled by QThread

  1. #1
    Join Date
    Apr 2009
    Posts
    13
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QMessageBox in slot signaled by QThread

    I have subclassed worker QThread that is sending results of it's work in signal to a slot.

    Within the slot I call QMessageBox::question(..) to let user confirm action based on thread's result. However if there comes more than one signal at once msgbox is shown for each of them before previous ones have been answered. So I end up with multiple boxes on screen.

    If I use Qt::BlockingQueuedConnection instead there is no problem, but worker thread won't do it's work in background while the box is shown.

    I don't quite understand how Qt event processing works but it seems like it blocks for the QMessageBox::qeustion(..) but still by some black magic (or not) it gets to resume event processing and finally calls the same slot function again...

    How could I prevent the slot from being called until it has been returned while letting worker thread keep doing it's job? Or is Qt::BlockingQueuedConnection the only way?

    Thanks for any ideas

  2. #2
    Join Date
    Jun 2007
    Location
    India
    Posts
    1,042
    Thanks
    8
    Thanked 133 Times in 128 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QMessageBox in slot signaled by QThread

    in your slot use QMutex..

    Qt Code:
    1. QMutex mutex; //make sure it is global or a static member of a class
    2. void myslot()
    3. {
    4. if(mutex.tryLock()) //u can use mutex.lock() but it will block..
    5. {
    6. QMessageBox::information();
    7. mutex.unlock();
    8. }
    9.  
    10. }
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Apr 2009
    Posts
    13
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QMessageBox in slot signaled by QThread

    Here is the original code I had in the slot

    Qt Code:
    1. void FileDatabase::taskFinished(WorkerTask* worktask)
    2. {
    3. switch (worktask->id())
    4. {
    5. ...
    6. case DBTASK_DELETE:
    7. {
    8.  
    9. // Double Check for accidental fallthroughs
    10. if (worktask->id() != DBTASK_DELETE) break;
    11.  
    12. if (d->deleteConfirmation == QMessageBox::Cancel) break;
    13.  
    14. FileModifiedTask* task = static_cast<FileModifiedTask*>(worktask);
    15. FileNode* fn = task->file();
    16.  
    17. if (task->isModified()) {
    18. Log(LOG_WARN) << tr("File has been modified; won't delete (%1)")
    19. .arg(fileRelativePath(fn)) << Log::ENDL;
    20. break;
    21. }
    22.  
    23. if (d->deleteConfirmation != QMessageBox::YesToAll)
    24. {
    25. d->deleteConfirmation = QMessageBox::question(
    26. app, tr("File About to be Deleted"),
    27. tr("Are you sure you want to delete %1 file '%2' ?\n\n"
    28. "WARNING: File will be removed from filesystem and it "
    29. "can't be restored!\n")
    30. .arg(FileAttributeString(fn), fileRelativePath(fn)),
    31. QMessageBox::Yes|QMessageBox::No|
    32. QMessageBox::YesToAll|QMessageBox::Cancel,
    33. }
    34.  
    35. if (d->deleteConfirmation&
    36. (QMessageBox::Yes|QMessageBox::YesAll))
    37. {
    38. QFile file(fn->path());
    39. if (file.remove())
    40. removeFile(fn);
    41. else {
    42. Log(LOG_ERROR) <<
    43. tr("Can't delete file (%1)")
    44. .arg(fileRelativePath(fn)) << Log::ENDL;
    45. }
    46. }
    47. }
    48. break;
    49. }
    50.  
    51. delete worktask;
    52. }
    To copy to clipboard, switch view to plain text mode 

    Worker thread computes hash of file content and the result is stored in FileModifiedTask and then emitted to the slot. In the slot I check if the file has been modified and confirm the file delete, unless it's been canceled or YesToAlled.

    So I thought about your suggestion to use mutex. In this case wouldn't simple bool variable be enough? I would assume this happens in single thread ? But then the problem becomes what to do with those tasks that can't get the lock ?

    So I thought it a bit more and then realised I need to store those finished tasks and process them later


    Qt Code:
    1. QObject::connect(taskTimer, SIGNAL(timeout()),
    2. db, SLOT(processQueuedTasks()));
    3.  
    4. void FileDatabase::taskFinished(WorkerTask* task)
    5. {
    6. d->taskQueue.enqueue(task);
    7. if (!(d->taskTimer->isActive() || d->processingTasks))
    8. d->taskTimer->start();
    9. }
    10.  
    11. void FileDatabase::processQueuedTasks()
    12. {
    13. d->processingTasks = true;
    14.  
    15. QTime time;
    16. time.start();
    17. int n = d->taskQueue.size();
    18. while (d->taskQueue.size() && time.elapsed() < 10) {
    19. processTask(d->taskQueue.dequeue()); // same code as in original taskFinished(..)
    20. }
    21. emit progressAdvanced(n - d->taskQueue.size());
    22. if (d->taskQueue.size())
    23. d->taskTimer->start();
    24.  
    25. if (d->batchFinished && d->taskQueue.isEmpty())
    26. unlock();
    27.  
    28. d->processingTasks = false;
    29. }
    To copy to clipboard, switch view to plain text mode 

    Not very pretty but but at least it seems to work...

    Btw am I correct when I think that each time QMessageBox::question() is called a new EventLoop is pushed on stack that now handles the gui events and all the other event that the previous "main" EventLoop did ? That in a sense there are then multiple EventLoops on stack, but only top one is "active"? I hope I'm not too off the mark here

Similar Threads

  1. Executing slots in a separate QThread?
    By kachofool in forum Newbie
    Replies: 3
    Last Post: 11th December 2009, 20:02
  2. what if qthread call same slot at the same time?
    By zl2k in forum Qt Programming
    Replies: 2
    Last Post: 11th September 2008, 09:58
  3. Replies: 2
    Last Post: 23rd May 2008, 13:22
  4. Communication between QThread and Yes/No QMessageBox?
    By pmaktieh.sirhc in forum Qt Programming
    Replies: 11
    Last Post: 25th January 2007, 03:45
  5. QThread, QMessageBox, gui thread
    By TheKedge in forum Qt Programming
    Replies: 1
    Last Post: 25th October 2006, 12:23

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.