A bug was found when calling qApp->quit()
-
When a modal dialog box is running (QMessagebox::exec()), calling qApp->quit() cannot exit the application, but directly closes the modal dialog box. If qApp->quit() is replaced with exit(0), the function will not execute atexit() function (it will run normally) and directly close the program.
-
When a modal dialog box is running (QMessagebox::exec()), calling qApp->quit() cannot exit the application, but directly closes the modal dialog box. If qApp->quit() is replaced with exit(0), the function will not execute atexit() function (it will run normally) and directly close the program.
@Pleafles That is an expected behavior because it is Qt I recommend not using
exec()
butopen()
as the docs indicates:Note: Avoid using this function; instead, use open(). Unlike exec(), open() is asynchronous, and does not spin an additional event loop. This prevents a series of dangerous bugs from happening (e.g. deleting the dialog's parent while the dialog is open via exec()). When using open() you can connect to the finished() signal of QDialog to be notified when the dialog is closed.
-
Thank you very much, but I do need modal dialog boxes in some places, and I also use some other methods to solve my problem, but I hope to solve this problem at the bottom, so I'll give you some suggestions
@Pleafles said in A bug was found when calling qApp->quit():
Thank you very much, but I do need modal dialog boxes in some places
calling exec() on a dialog doesn't make it a modal one, calling setModal
If you mean with modal, you want to remain in the function until the dialog is closed, that different and a sign of bad design. One can easily work around that. -
When a modal dialog box is running (QMessagebox::exec()), calling qApp->quit() cannot exit the application, but directly closes the modal dialog box. If qApp->quit() is replaced with exit(0), the function will not execute atexit() function (it will run normally) and directly close the program.
@Pleafles said in A bug was found when calling qApp->quit():
When a modal dialog box is running (QMessagebox::exec()), calling qApp->quit() cannot exit the application, but directly closes the modal dialog box.
This works correctly:
#include <QApplication> #include <QDialog> #include <QMainWindow> #include <QTimer> int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow window; QMetaObject::invokeMethod(&a, [&window] () -> void { QDialog dialog(&window); QTimer::singleShot(5000, [] () -> void { qApp->quit(); }); dialog.exec(); }, Qt::QueuedConnection); window.show(); return a.exec(); }
so I'm not convinced.
If qApp->quit() is replaced with exit(0), the function will not execute atexit() function (it will run normally) and directly close the program.
If you terminate the application, it's going to be terminated. How is this strange?
https://en.cppreference.com/w/cpp/utility/program/exit -
@Pleafles said in A bug was found when calling qApp->quit():
Thank you very much, but I do need modal dialog boxes in some places
calling exec() on a dialog doesn't make it a modal one, calling setModal
If you mean with modal, you want to remain in the function until the dialog is closed, that different and a sign of bad design. One can easily work around that. -
@Pleafles said in A bug was found when calling qApp->quit():
When a modal dialog box is running (QMessagebox::exec()), calling qApp->quit() cannot exit the application, but directly closes the modal dialog box.
This works correctly:
#include <QApplication> #include <QDialog> #include <QMainWindow> #include <QTimer> int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow window; QMetaObject::invokeMethod(&a, [&window] () -> void { QDialog dialog(&window); QTimer::singleShot(5000, [] () -> void { qApp->quit(); }); dialog.exec(); }, Qt::QueuedConnection); window.show(); return a.exec(); }
so I'm not convinced.
If qApp->quit() is replaced with exit(0), the function will not execute atexit() function (it will run normally) and directly close the program.
If you terminate the application, it's going to be terminated. How is this strange?
https://en.cppreference.com/w/cpp/utility/program/exit@kshegunov Thank you very much, it works normally, but there will be problems with its use:
...
QApplication a(argc, argv);
QMainWindow window;
window.show();QDialog dialog(&window); QTimer::singleShot(5000, [] () -> void { qApp->quit(); }); dialog.exec(); return a.exec();
It's strange why this doesn't work,and and it will crash...
-
@kshegunov Thank you very much, it works normally, but there will be problems with its use:
...
QApplication a(argc, argv);
QMainWindow window;
window.show();QDialog dialog(&window); QTimer::singleShot(5000, [] () -> void { qApp->quit(); }); dialog.exec(); return a.exec();
It's strange why this doesn't work,and and it will crash...
@Pleafles said in A bug was found when calling qApp->quit():
It's strange why this doesn't work,and and it will crash...
[EDIT: Sorry, this is wrong. Please get a stack trace, as @kshegunov suggested]
Because your code will try to delete the dialog twice. See https://doc.qt.io/qt-5/objecttrees.html#construction-destruction-order-of-qobjectsYou must do one of the following:Do not set a parent for your dialog, ORAllocate the dialog on the heap (by callingnew QDialog
), not on the stack
-
@Pleafles said in A bug was found when calling qApp->quit():
It's strange why this doesn't work,and and it will crash...
[EDIT: Sorry, this is wrong. Please get a stack trace, as @kshegunov suggested]
Because your code will try to delete the dialog twice. See https://doc.qt.io/qt-5/objecttrees.html#construction-destruction-order-of-qobjectsYou must do one of the following:Do not set a parent for your dialog, ORAllocate the dialog on the heap (by callingnew QDialog
), not on the stack
@JKSH said in A bug was found when calling qApp->quit():
Because your code will try to delete the dialog twice. See https://doc.qt.io/qt-5/objecttrees.html#construction-destruction-order-of-qobjects
Pardon? Why, where?
You must do one of the following:
- Do not set a parent for your dialog, OR
Parents go beyond the simple memory management, they're also responsible for drawing surfaces (a.k.a. window handles/native windows). So now you should explain, why "you must not" ...
- Allocate the dialog on the heap (by calling
new QDialog
), not on the stack
... nope!
-
@kshegunov Thank you very much, it works normally, but there will be problems with its use:
...
QApplication a(argc, argv);
QMainWindow window;
window.show();QDialog dialog(&window); QTimer::singleShot(5000, [] () -> void { qApp->quit(); }); dialog.exec(); return a.exec();
It's strange why this doesn't work,and and it will crash...
@Pleafles said in A bug was found when calling qApp->quit():
It's strange why this doesn't work,and and it will crash...
No offence, but I don't feel like guessing. Please get a stack trace and post it here.
-
@JKSH said in A bug was found when calling qApp->quit():
Because your code will try to delete the dialog twice. See https://doc.qt.io/qt-5/objecttrees.html#construction-destruction-order-of-qobjects
Pardon? Why, where?
You must do one of the following:
- Do not set a parent for your dialog, OR
Parents go beyond the simple memory management, they're also responsible for drawing surfaces (a.k.a. window handles/native windows). So now you should explain, why "you must not" ...
- Allocate the dialog on the heap (by calling
new QDialog
), not on the stack
... nope!
@kshegunov said in A bug was found when calling qApp->quit():
@JKSH said in A bug was found when calling qApp->quit():
Because your code will try to delete the dialog twice. See https://doc.qt.io/qt-5/objecttrees.html#construction-destruction-order-of-qobjects
Pardon? Why, where?
My bad, my assessment was wrong. Double-deletion won't happen here since the QDialog will be deleted before the QMainWindow.
So the problem is somewhere else.
-
@kshegunov said in A bug was found when calling qApp->quit():
@JKSH said in A bug was found when calling qApp->quit():
Because your code will try to delete the dialog twice. See https://doc.qt.io/qt-5/objecttrees.html#construction-destruction-order-of-qobjects
Pardon? Why, where?
My bad, my assessment was wrong. Double-deletion won't happen here since the QDialog will be deleted before the QMainWindow.
So the problem is somewhere else.
@JKSH said in A bug was found when calling qApp->quit():
So the problem is somewhere else.
Indeed. My speculation is that the local event loop is run before the global one, but ... a trace is the way to go, as usual.
-
@JKSH said in A bug was found when calling qApp->quit():
So the problem is somewhere else.
Indeed. My speculation is that the local event loop is run before the global one, but ... a trace is the way to go, as usual.
@kshegunov I found the problem, as you said, the local event loop is run before the global one(QMessageBox::info() is called in constructor),but why? Where can I explain?