Results 1 to 5 of 5

Thread: QMessageBox.exec() does not block Producer-Consumer signal loop

  1. #1
    Join Date
    Apr 2012
    Posts
    17
    Qt products
    Qt4
    Platforms
    Windows

    Default QMessageBox.exec() does not block Producer-Consumer signal loop

    Hi!,
    I have a singlethreaded application which performs some longer task. The task is devided in to small portions and accomplished by Producer-Consumer, Qt::QueuedConnection, signal-slot loop. Everthing works well, gui is responsive.
    I have a 'Stop' button in the gui. In its 'onClick' event handler i am displaying a confirmation message with use of QMessageBox::exec() function.

    Unfortunately i am facing the following problem:
    When the confirmation message is displayed, sometimes the Producer-Consumer loop is blocked and sometimes it proceeds unaffected.
    I would like the modal confirmation box to block the execution of the Producer-Consumer loop.

    I have read that exec() runs its own event loop and this would explain why Producer-Consumer loop proceeds. However, i am confused with the fact that sometimes it is blocked. And still.. i would like to block this loop somehow.

    Any ideas?
    best regards.
    Last edited by airproject; 30th August 2012 at 11:48.

  2. #2
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QMessageBox.exec() does not block Producer-Consumer signal loop

    exec() makes another event loop - but you can think of this as another version of the gui event loop.

    I dont think it will be interfering with the running of other threads, and I think it should not be halting the execution of slots in the gui thread.

    If you want to be able to block your producer/consumer, I suggest looking at something like this:
    Qt Code:
    1. void
    2. myclass::slot_block()
    3. {
    4. QEventLoop eventLoop;
    5. connect(this, SIGNAL(continue()), &eventLoop, SLOT(quit()));
    6. eventLoop.exec(); // will process signals/slots, but myclass
    7. // will not otherwise execute any more code until the loop is exited
    8. }
    9.  
    10. void
    11. myclass::slot_continue()
    12. {
    13. emit continue();
    14. }
    To copy to clipboard, switch view to plain text mode 
    ie you need to implement two slots and a signal.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  3. #3
    Join Date
    Apr 2012
    Posts
    17
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QMessageBox.exec() does not block Producer-Consumer signal loop

    Thank you for the reply.
    If i understand you well:
    - QMessageBox::exec() - executes an event loop which processes the GUI thread signals (processes Producer-Consumer, filters out only widget signals?)
    - creating new QEventLoop and running it will be processing utterly new event loop separated form GUI thred with Producer-Consumer signals. This loop will engage application processing untill i quit() it.

    I guess Displaying QMessageBox should be accomplished with some other method (open(), show()) than exec().

    I will do some trials.. and still wonder why sometimes the GUI thread event loop is blocked by exec() and sometimes no:/

    Best regards.

  4. #4
    Join Date
    Apr 2012
    Posts
    17
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QMessageBox.exec() does not block Producer-Consumer signal loop

    Thanks to amleto I have identified reason why the Consumer-Producer loop soemtimes is blocked by QMessageBox::exec().

    In the Consumer method i have used the following pattern to synchronize asynchronous operation:
    Qt Code:
    1. QNetworkAccessManager manager;
    2. QTimer tT;
    3.  
    4. tT.setSingleShot(true);
    5. connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
    6. connect(&manager, SIGNAL(finished(QNetworkReply*)),
    7. &q, SLOT(quit()));
    8. QNetworkReply *reply = manager.get(QNetworkRequest(QUrl("http://www.qtcentre.org")));
    9.  
    10. tT.start(5000); // 5s timeout
    11. q.exec();
    12.  
    13. if(tT.isActive()){
    14. // download complete
    15. tT.stop();
    16. } else {
    17. // timeout
    18. }
    To copy to clipboard, switch view to plain text mode 

    - If the 'Stop' button is pressed and its OnClick method containing QMessageBox::exec() is executed when Consumer is at q.exec() line , the appliction stops execution at q.exec() line untill the QMessagBox dialog is closed.
    - Contrary, if the Stop' button is pressed, and its OnClick method containing QMessageBox::exec() is executed before or after Consumer q.exec() line, then Consumer-Producer loop continues to work.

    It looks like neither
    connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
    nor
    connect(&manager, SIGNAL(finished(QNetworkReply*)),
    signal can reach its slot and finish q.exec() event loop when QMessageBox::exec() is executed. It looks like what amleto proposed with exception that the QMessageBox::exec() is blocking q.exec() event loop.

    How could i make the application running, and not lock on q.exec()?


    Added after 18 minutes:


    Problem solved.
    1. The Producer-Consumer signal loop was blocked by the QEventLoop q.exec() which could not be finished due to QMessagBox which was exec()uted while q.exec() was running. When event loop is running it cannot be interrupted by QMessageBox.exec:
    "Generally speaking, no user interaction can take place before calling exec(). As a special case, modal widgets like QMessageBox can be used before calling exec(), because modal widgets use their own local event loop."http://doc.qt.io/qt-4.8/http://qt-project.org/doc/qt-4.8/qeventloop.html#exec

    2. To avoid locking of EventLoop by some messages which are displayed in GUI slots, it is enough to exec()ute the event loop with parameter QEventLoop::ExcludeUserInputEvents:
    "Do not process user input events, such as ButtonPress and KeyPress. Note that the events are not discarded; they will be delivered the next time processEvents() is called without the ExcludeUserInputEvents flag."http://doc.qt.io/qt-4.8/http://qt-project.org/doc/qt-4.8/qeventloop.html#ProcessEventsFlag-enum

    3. If someone wants to block totaly all events in the GUI thread when the QMessageBox is exec()uted, try amaleto solution with additional QEventLoop.

    Thanks.
    Last edited by airproject; 30th August 2012 at 19:23.

  5. #5
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QMessageBox.exec() does not block Producer-Consumer signal loop

    thanks for investigation & feedback
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

Similar Threads

  1. Any Qt code/example for producer consumer pattern?
    By Sheng in forum Qt Programming
    Replies: 1
    Last Post: 23rd February 2009, 21:11
  2. Replies: 16
    Last Post: 28th October 2008, 22:00
  3. Speed up Producer Consumer Threads
    By ^NyAw^ in forum Qt Programming
    Replies: 7
    Last Post: 29th February 2008, 18:38
  4. Producer Consumer...
    By Shuchi Agrawal in forum Newbie
    Replies: 1
    Last Post: 16th February 2007, 09:45
  5. Producer Consumer
    By ^NyAw^ in forum Qt Programming
    Replies: 16
    Last Post: 17th November 2006, 19:53

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.