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:
QNetworkAccessManager manager;
tT.setSingleShot(true);
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
connect(&manager, SIGNAL(finished(QNetworkReply*)),
&q, SLOT(quit()));
QNetworkReply
*reply
= manager.
get(QNetworkRequest
(QUrl("http://www.qtcentre.org")));
tT.start(5000); // 5s timeout
q.exec();
if(tT.isActive()){
// download complete
tT.stop();
} else {
// timeout
}
QNetworkAccessManager manager;
QEventLoop q;
QTimer tT;
tT.setSingleShot(true);
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
connect(&manager, SIGNAL(finished(QNetworkReply*)),
&q, SLOT(quit()));
QNetworkReply *reply = manager.get(QNetworkRequest(QUrl("http://www.qtcentre.org")));
tT.start(5000); // 5s timeout
q.exec();
if(tT.isActive()){
// download complete
tT.stop();
} else {
// timeout
}
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.
Bookmarks