My experience in Qt is about two weeks, excuse me if I happen to ask a stupid question.
My program uses QtQuick-based GUI. I initialise it in my main.cpp
#include <QGuiApplication>
#include <QtQuick/QQuickView>
#include "VeryVeryImportantItem.h"
extern
int main(int argc, char * argv[])
{
qmlRegisterType<VeryVeryImportantItem>("com.my.stuff", 1, 0, "VeryVeryImportantItem");
QQuickView quickView(QUrl("MyView.qml"));
quickView.show();
QGuiApplication app;
return app.exec();
}
And MyView.qml looks like this:
import QtQuick 2.1
import QtQuick.Window 2.1
import com.my.stuff 1.0
Item VeryVeryImportantItem {
id : veryVeryImportantItem
...
}
And VeryVeryImportantItem.h is as follows:
#include <QtQuick/QQuickItem>
class VeryVeryImportantItem : public QQuickItem
{
Q_OBJECT
public:
Q_INVOKABLE void cleanup();
...
};
And now the problem. How do I intercept close event on my root window/view, call VeryVeryImportantItem::cleanup(); and only after that close the application?
What I've found out by now is that QQuickItem::window()
can give me the pointer to the window I need and that the window has signal QQuickWindow::closing(QQuickCloseEvent *);
and that in theory I can prevent the window from closing by manipulating the given QQuickCloseEvent
object. But it's not public, I don't have access to its methods!
Ok. Another way might be that I could do something similar from QML. QML type QWindow
has closing(CloseEvent)
signal and if I set CloseEvent.accepted
false in a slot connected to it that would prevent the window from immediate closing and enable me to call veryVeryImportantItem.cleanup()
method. But then I have another problem: how do I get the reference to my root window if I've created it not in QML but in C++ start-up code.
I guess this is the very common situation and there obviously ought to be a well-defined way to handle this but I've been googling for some four hours and still haven't found any decent explanation.
You can intercept the close event on QQuickView. To do it, create a derived class and overrides the event method:
class NewQuickView: public QQuickView {
public:
NewQuickView(QUrl url):
QQuickView(url) {}
public:
bool event(QEvent *event) override
{
if (event->type() == QEvent::Close) {
// your code here
}
return QQuickView::event(event);
}
};
on main, instance your new class:
NewQuickView quickView(QUrl("MyView.qml"));
I guess this is the very common situation and there obviously ought to be a well-defined way to handle this
Yes, one could say that.
The easiest thing to do would be to switch to using QQmlApplicationEngine
and on the QML side ApplicationWindow
as your root component.
Then you can simply use the onClosing
signal handler to run your cleanup. I have a similar scenario, where the app would crash if closed before cleanup was invoked, and this approach works flawlessly.
//main.cpp
QQmlApplicationEngine engine;
engine.load(QUrl("MyView.qml"));
.
ApplicationWindow {
visible: true
width: 1280
height: 720
BoxView {
id: view
}
onClosing: {
view.deleteView()
}
}
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