I am trying to catch a close event either in my MyApplication
instance inheriting from QApplication
or in my WindowQML
instance inheriting from QQuickView
. The goal is to ask confirmation to quit before really closing the application.
Before my application was relying on QMainWindow
where I implemented the closeEvent()
method like this:
// MainWindow inherits from QMainWindow
void MainWindow::closeEvent(QCloseEvent *event)
{
event->ignore();
confirmQuit(); // ask for confirmation first
}
The problem is that my class WindowQML
which inherits from QQuickView
never pass inside the closeEvent()
method. I then tried to overload the event()
method like this:
// WindowQML inherits from QQuickView
bool WindowQML::event(QEvent *event)
{
if(event->type() == QEvent::Close)
{
qDebug() << "CLOSE EVENT IN QML WINDOW";
}
}
but this event never happened either.
The next road I tried to take was to catch the close event in MyApplication
like this:
// We need to check for the quit event to ask confirmation in the QML view
bool MyApplication::event(QEvent *event)
{
bool handled = false;
switch (event->type())
{
case QEvent::Close:
qDebug() << "Close event received";
event->ignore(); // mandatory?
handled = true;
Q_EMIT quitSignalReceived();
break;
default:
qDebug() << "Default event received";
handled = QApplication::event(event);
break;
}
qDebug() << "Event handled set to : " << handled;
return handled;
}
The signal quitSignalReceived()
is emitted properly but the event is not "blocked" properly and my application still closes.
So I have two questions:
QQuickView
instance?MyApplication::event()
way the best course of action? Why do I need to call event->ignore()
here? I would have thought that returning true
would be enough.I was under the impression that qApp->quit () is the right way to exit the app, and the right slot to connect the "File -> Exit" menu action to. But it bypasses QMainWindows::closeEvent (), which often triggers, directly or indirectly, some cleanup and finalization. Bypassing it causes bugs in applications.
The QQuickView class provides a window for displaying a Qt Quick user interface. More... This is a convenience subclass of QQuickWindow which will automatically load and display a QML scene when given the URL of the main source file.
But most of the time you will get a confirmation. But there's a stupid behavior by design: If the app is minimized, it won't be closed via the context menu until you restore the app.
Asking for confirmation sets your mind at ease. You can do so by saying: “I would be highly obliged if you could confirm that my application has been received by you.” “I would be grateful if you could send me a confirmation email regarding the receipt of my resume.”
I don't know why QWindow
hasn't a closeEvent
convenience event handler. Looks like a mistake, and sadly it can't be added before Qt 6.0. Anyhow, any QWindow definitely gets a QCloseEvent
when it gets closed. So just override event
and perform your event handling there.
Proofs:
this test program:
#include <QtGui>
class Window : public QWindow
{
protected:
bool event(QEvent *e) Q_DECL_OVERRIDE
{
int type = e->type();
qDebug() << "Got an event of type" << type;
if (type == QEvent::Close)
qDebug() << "... and it was a close event!";
return QWindow::event(e);
}
};
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
Window w;
w.create();
w.show();
return app.exec();
}
prints this
Got an event of type 17
Got an event of type 14
Got an event of type 13
Got an event of type 105
Got an event of type 13
Got an event of type 206
Got an event of type 206
Got an event of type 8
Got an event of type 207
Got an event of type 19
... and it was a close event!
Got an event of type 18
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With