QMessageBox refuses to close
-
I have a QMessage box that I cannot close anymore since I changed the way I declare it. What could be causing a QWidget to refuse closing?
@bool closeRes=comMsg->close(); //returns false and the messagebox does not close@QmainWIndow Header which contains a couple of slot related to it:
@ QPushButton * pbFindNewFcp;
QPushButton * pbComExit;
QMessageBox * comMsg;void doQueryUserOnCommLoss(){ comMsg->setWindowTitle(tr("Communication Latency")); comMsg->setText(tr(COM_LATENCY_MSGBOX_STRING)); comMsg->show(); } void onFindNewFcpClicked(){ pFPSengine->findAnotherFcp=true; //raise a flag that will make the reconnection handler cycle through its list of ip addresses comMsg->setText("Looking for an active FCP"); comMsg->show(); } void onComExitClicked(){ QCloseEvent * dumyEvent= new QCloseEvent(); if(closeEventHandler(dumyEvent)){ comMsg->close(); } else if(!pFPSengine->FCPisConnected){ comMsg->setText(tr(COM_LATENCY_MSGBOX_STRING)); comMsg->show(); } } void do_recoverFPSfromComLoss(){ bool closed=comMsg->close(); }
@
QMainwindow constructor:@ comMsg = new QMessageBox(this);
pbFindNewFcp =comMsg->addButton("Find Another Fcp",QMessageBox::ActionRole);
pbComExit= comMsg->addButton("Exit",QMessageBox::ActionRole);
connect(this->pbFindNewFcp,SIGNAL(clicked()),this,SLOT(onFindNewFcpClicked()));
connect(this->pbComExit,SIGNAL(clicked()),this,SLOT(onComExitClicked()));
@ -
A QMessageBox is supposed to be shown with exec(), this makes the message box modal (relative to the current window or the complete application). I doubt, that your way of displaying the message box with show() will ever work.
For your use case, it seems that you'd better pay off by subclassing [[Doc:QDialog]], setup a some UI components and add some slots. QDialogs can be shown modeless using show() without problems.
Also, depending on the use case, a [[Doc:QProgressDialog]] could probably be of use for you too.
-
Thanks for your reply. The issue is not with calling show(), I have been able to do this more than once and I also use exec(). It is just in this context that the QMessageBox does not close. If you look in the Qt doc for the definition of QMessageBox::exec() you will see that at the end of the definition it says"
bq. See also show() and result().
In that case, why would the documentation refer to show() if it should not be used. I do understand though that calling exec() should be the preferred way to do it but I would like to get to the bottom of this before I move on.
-
Also, one thing I failed to mention: I need to be able to close the QMessageBox programatically from the background when it is no longer needed (it is a message box that can close by itself.) Also, I never said I wanted a non modal window, I actually need it to be application modal.
-
Can you give us a complete example which can reproduce the problem?
For example, like this:
@
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtGui/QMessageBox>
#include <QtGui/QPushButton>class Widget:public QWidget
{
Q_OBJECTpublic:
Widget()
{
msgBox = new QMessageBox(this);
btn = msgBox->addButton("&Click Me", QMessageBox::AcceptRole);
connect(btn, SIGNAL(clicked()),SLOT(closeMsgBox()));
}
protected:
void mouseDoubleClickEvent(QMouseEvent *)
{
QTimer::singleShot(5000, btn, SLOT(click()));
msgBox->show();
// msgBox->exec();
}
private slots:
void closeMsgBox()
{
//...
msgBox->close();
}private:
QMessageBox * msgBox;
QPushButton * btn;
};
#include "main.moc"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.isVisible();
w.show();return a.exec();
}
@whether or not you using show() or exec(), it does not change the fact: QMessageBox is an modal widget unless you clear its modal property.
-
Try this:
@QMessageBox *msgBox = new QMessageBox(this);
msgBox->setButtonText(QMessageBox::Yes, "Find Another Fcp");
msgBox->setButtonText(QMessageBox::Cancel, "Exit");
msgBox->exec();@You may also follow this:
Advanced Usage at "QMessageBox":http://doc.qt.nokia.com/latest/qmessagebox.html -
[quote author="yan bellavance" date="1314662511"]Also, one thing I failed to mention: I need to be able to close the QMessageBox programatically from the background when it is no longer needed (it is a message box that can close by itself.) Also, I never said I wanted a non modal window, I actually need it to be application modal. [/quote]
For it to be application modal, you must call exec. The flow of control will only return after exec has finished (this implicitly closes the message box).
So for your message box to close programmatically, you are in need of a second thread, that can run independently. Do you have one?
-
[quote author="Volker" date="1314722051"]
[quote author="yan bellavance" date="1314662511"]Also, one thing I failed to mention: I need to be able to close the QMessageBox programatically from the background when it is no longer needed (it is a message box that can close by itself.) Also, I never said I wanted a non modal window, I actually need it to be application modal. [/quote]For it to be application modal, you must call exec. The flow of control will only return after exec has finished (this implicitly closes the message box).
So for your message box to close programmatically, you are in need of a second thread, that can run independently. Do you have one?[/quote]
To avoid that, Qt 4.5 introduced open() on (almost?) all QDialog subclasses. That opens a window-modal dialog, but returns immediately, just like show() does. Moreover, you can pass a QObject and a SLOT to be invoked when the QMessageBox is discarded.
-
[quote author="peppe" date="1314722475"]
To avoid that, Qt 4.5 introduced open() on (almost?) all QDialog subclasses.
[/quote]You're right. I forgot about those.
So, this snippet works for me:
@
QMessageBox *_msgBox;
_msgBox = new QMessageBox(this);
_msgBox->setButtonText(QMessageBox::Yes, "Find Another Fcp");
_msgBox->setButtonText(QMessageBox::Cancel, "Exit");
_msgBox->setText("I do something");
_msgBox->open();
for(int i = 1; i < 5; ++i) {
qDebug() << "sleep round" << i;
sleep(1);
QApplication::processEvents();
}
qDebug() << "closing the box";
_msgBox->close();
@ -
Thanks for your answers. I never had time to figure out why it refused to close. I ended up implementing one of the standard solutions you provided instead.
-