Custom Synchronous Message Dialog with QEventLoop
-
Hello. I'm working on a desktop application using QtQuick. It's a wizard-like application, and I would like to have only one window. I'm trying to make a custom message dialog control to match my application graphics. It would be better if it were synchronous, because then I wouldn't need a slot every time I show a message, as most of the times I need user input (OK,Cancel,Yes,No) in order to proceed. It's working as expected, except for one issue. I don't like posting lots of code, but there was not other way this time. I'm sorry. Let's say this is my main window:
ApplicationWindow { Button { text: "Do Task" onClicked: controller.doTask() } Rectangle { id: msgRec anchors.fill: parent /* takes the whole window */ visible: false MouseArea { /* blocks user input on controls behind */ anchors.fill: parent } Text { id: msgText } Button { text: "OK" onClicked: { msgRec.visible = false; msgbox.endShow(); } } Connections { target: msgbox onShow: { msgText.text = message; msgRec.visible = true; } } } }
"msgbox" and "controller" are C++ classes.
class MyMsgBox : public QObject { Q_OBJECT private: QEventLoop* myLoop; public: MyMsgBox(QObject *parent) : QObject(parent){ myLoop = NULL; } static MyMsgBox* getInstance(){ static MyMsgBox* instance = NULL; if(instance == NULL) instance = new MyMsgBox; return instance; } static void alert(QString message){ MyMsgBox::getInstance()->beginShow(message); } int beginShow(QString message){ qDebug() << "beginShow()"; /* happens on showing dialog and on first clicking OK */ if(myLoop != NULL) return -1; this->show(message); myLoop = new QEventLoop(this); myLoop->exec(); delete myLoop; myLoop = NULL; return 0; // it will return the button index } Q_INVOKABLE void endShow(){ myLoop->exit(0); } signals: void show(QString message); } class MyController : public QObject { Q_OBJECT public: Q_INVOKABLE void doTask() { // ... MyMsgBox::alert("Hello world!"); // ... } } //============= context->setContextProperty("controller", MyController()); context->setContextProperty("msgbox", MyMsgBox::getInstance());
When the user clicks on the "OK" button, it fires "beginShow" again. Then, when he clicks again, now it fires "endShow" as it should and dismisses the dialog. It's so weird I'm having a hard time putting it into words. Please, check this image:
So, any ideas about what might be going on?
Thank you.
-
Hi and welcome to devnet,
Not really an answer but, why not use a state machine ? That would make your code logic more wizard like and might avoid the use of that QEventLoop
Hope it helps