closing child object causes parent to be closed
-
This is a simple description of my program:
There are three QDialog, named a, b, c.
a is the common parent of b and c.
a is invisible(e.g. show() isn't called), b and c are visible.
when either b or c is closed, the entire application exits.Why?
if you want to know more, here is the core codeclass Dialog:public QDialog{ Q_OBJECT; private slots: void on_button_clicked() { Dialog * dialog = new Dialog(this->parentWidget()); //share the same parent dialog->show(); } public: Dialog(QWidget *parent = 0): QDialog(parent) { qDebug() << "my address " << this << ", parent address " << this->parentWidget(); ui = new Ui::Dialog(); ui->setupUi(this); } ~Dialog() { qDebug() << "~Dialog"; } private: Ui::Dialog *ui; }; int main(int argc, char **argv) { QApplication app(argc, argv); Dialog a;//parent Dialog Dialog *b = new Dialog(&a);//child Dialog b->show(); return app.exec(); }
so the main function creates two Dialogs, the parent is invisible and the child is visible. and i click the button on the child Dialog, a new Dialog pops up, at this moment if i close any one of these two Dialogs, the whole program terminates.
-
Hi and welcome to devnet
What kind of signals you have connected to the dialogs?
There is most likely the key question.You need to post some code snippets to show others what you are actually doing for proper answers.
-
Hi
Application has a setting
setQuitOnLastWindowClosed
http://doc.qt.io/qt-5/qguiapplication.html#quitOnLastWindowClosed-propSo depending what flags u set on the dialogs, it might be the reason that app exits the exec() loop
-
class Dialog:public QDialog{ Q_OBJECT; private slots: void on_button_clicked() { Dialog * dialog = new Dialog(this->parentWidget()); //share the same parent dialog->show(); } public: Dialog(QWidget *parent = 0): QDialog(parent) { qDebug() << "my address " << this << ", parent address " << this->parentWidget(); ui = new Ui::Dialog(); ui->setupUi(this); } ~Dialog() { qDebug() << "~Dialog"; } private: Ui::Dialog *ui; }; int main(int argc, char **argv) { QApplication app(argc, argv); Dialog a;//parent Dialog Dialog *b = new Dialog(&a);//child Dialog b->show(); return app.exec(); }
so the main function creates two Dialogs, the parent is invisible and the child is visible. and i click the button on the child Dialog, a new Dialog pops up, at this moment if i close any one of these two Dialogs, the whole program terminates.
-
@fireyyouth
you should try with
app.setQuitOnLastWindowClosed(false); -
@fireyyouth
Yes but if only one is considered toplevel ( never tested with only Dialogs) , it would still close.
At least for testing. then we know its not due to the auto close feature.
If it stills quits, its something else.Also you can add a a line after app.exec() and put break point on it.
That way we can see if the exit is due to normal reason or something else.I assume you didn't not hook up anything to the quit() slot or by other means added code to end application ?
-
I updated my question, please take a look
-
@fireyyouth
and did testing with
app.setQuitOnLastWindowClosed(false);
still close the whole app ? -
no the programs hangs
-
@fireyyouth
hangs?
The dialogs stays on screen but can no longer be clicked ?
or how hangs ? -
@fireyyouth
ahh, that is expected as we disable the auto close.
You must close it yourself using quit() in application.You can use DeleteOnclose on the dialog and call QApplication::quit() in destructor.
Of Course it depends on what design you're after.
So if you do this in Dialog ( the parent), it should do as you want. -
I get what you mean and i think it could work. thanks. but I still want to understand why the original case happened, can you explain?
-
@fireyyouth
I did not test it, but i think that a invisible dialog do not count as "window" and hence
it would auto close when you closed the dialog. ( even if not the last "window" )You can test if the dialog is considered that.
Its normally/used to be a flag. You set. QMianwindow has it.
Not sure with Dialogs in all cases. Where parent is also a Dialog
http://doc.qt.io/qt-5/qt.html#WindowType-enum
Also I could not find the exact doc on the rules for being top level and the auto close feature.
I did find that
"QDialog and QMainWindow widgets are by default windows, even if a parent widget is specified in the constructor. This behavior is specified by the Qt::Window flag."You could try the code, to see what is listed.
void showAllTopLevelWidgets() { foreach (QWidget *widget, QApplication::topLevelWidgets()) { // print out info } }
So overall the dialogs are not having WType_TopLevel if they have parents or something like that.
Where as QMainWindow has it.
You can give flags to Dialog in constructor so I think u can make it work like MW with some research.
I think WType_TopLevel is called something else. But not sure.
My Google fu failed me. Looking in the source code would bring light.