PDA

View Full Version : QMessageBox in initializeGL calls initializeGL one more time



DIMEDROLL
27th November 2010, 11:41
void MyGlWidget::initializeGL() {
try {
throw std::exception();
} catch(...) {
QMessageBox::critical(this, tr("Exception"),
tr("Exception occured"));
}
}

in catch() messagebox is shown and execution goes into initializeGL() again, and shows a second message box

I'm trying to avoid this via a bool variable:


void MyGlWidget::initializeGL() {
if(in_initializeGL_)
return;
in_initializeGL_ = true;

try {
throw std::exception();
} catch(...) {
QMessageBox::critical(this, tr("Exception"),
tr("Exception occured"));
}

in_initializeGL_ = false;
}

But this leads to crash. So I decided to show error in paintGL()(it also shows 2 messageboxes):


void MyGlWidget::paintGL() {
if(in_paintGL_)
return;
in_paintGL_ = true;

if (!exception_msg_.isEmpty()) {
QMessageBox::critical(this, tr("Exception"),
exception_msg_);
exception_msg_.clear();
}

// rendering stuff

in_paintGL_ = false;
}

void MyGlWidget::initializeGL() {
try {
throw std::exception();
} catch(...) {
exception_msg_ = "Exception in initializeGL()";
}
}

This solves the problem but the code is ugly. Is there a more nice solution of this problem?

high_flyer
27th November 2010, 23:34
Does this double showing of QMessageBox also happens when you construct the messagebox with a NULL parent?

DIMEDROLL
28th November 2010, 10:03
Yes.
The call stack is(from down to up):
...
initializeGL()
updateGL()
QMessageBox::critical()
initializeGL()

high_flyer
28th November 2010, 13:09
hmm... my guess is that it has to do with QMessageBox showing it self, while you are in a paintEvent() - that maybe forces a general paintEvent() on all the applications visible widgets, resulting in a recursive call.
But that is only a guess.

franz
28th November 2010, 19:28
Opening the QMessageBox using one of the static functions starts a new event loop. This is an Unpredictable exec() (http://labs.qt.nokia.com/2010/02/23/unpredictable-exec/) issue.

DIMEDROLL
28th November 2010, 20:04
Thanks! Nice article and solution.

void MyGlWidget::initializeGL() {
try {
throw std::exception();
} catch(...) {
getExceptionMessage(&exception_msg_);
QMessageBox *msgbox = new QMessageBox(QMessageBox::Warning,
"Exception",
exception_msg_,
QMessageBox::Ok,
this);
msgbox->open(0, 0);
}
}
Don't forget to use "new QMessageBox", because "QMessageBox msgbox;" will be deleted on scope exit. open() doesn't block the execution.