QtQuick:如何覆盖窗口关闭事件?

kro*_*bla 4 qt qml qtquick2

我在Qt的经历大概是两周,如果我碰巧问了一个愚蠢的问题,请原谅.

我的程序使用基于QtQuick的GUI.我在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();
}
Run Code Online (Sandbox Code Playgroud)

MyView.qml看起来像这样:

import QtQuick 2.1
import QtQuick.Window 2.1
import com.my.stuff 1.0

Item VeryVeryImportantItem {
    id : veryVeryImportantItem
    ...
}
Run Code Online (Sandbox Code Playgroud)

VeryVeryImportantItem.h如下:

#include <QtQuick/QQuickItem>

class VeryVeryImportantItem : public QQuickItem
{
    Q_OBJECT
public:
    Q_INVOKABLE void cleanup();
    ...
};
Run Code Online (Sandbox Code Playgroud)

而现在的问题.如何在我的根窗口/视图上拦截close事件,调用VeryVeryImportantItem :: cleanup(); 只有在那之后关闭申请?

我现在发现的是,它QQuickItem::window()可以给我指向我需要的窗口的指针,窗口有信号QQuickWindow::closing(QQuickCloseEvent *);,理论上我可以通过操纵给定的QQuickCloseEvent对象来防止窗口关闭.但它不公开,我无法访问其方法!

好.另一种方式可能是我可以用QML做类似的事情.QML类型QWindowclosing(CloseEvent)信号,如果我CloseEvent.accepted在连接到它的插槽中设置false,这将阻止窗口立即关闭并使我能够调用veryVeryImportantItem.cleanup()方法.但是我还有另外一个问题:如果我在QML中创建它而不是在C++启动代码中,我如何获得对我的根窗口的引用.

我想这是非常常见的情况,显然应该有一个明确的方法来处理这个问题,但我已经谷歌搜索了大约四个小时仍然没有找到任何正当的解释.

dte*_*ech 7

我想这是非常常见的情况,显然应该有一个明确的方法来处理这个问题

是的,有人可以这么说.

最简单的方法是切换到使用QQmlApplicationEngine和在QML端ApplicationWindow作为根组件.

然后你可以简单地使用onClosing信号处理程序来运行清理.我有一个类似的场景,如果在调用清理之前关闭应用程序会崩溃,这种方法可以完美地运行.

//main.cpp
QQmlApplicationEngine engine;
engine.load(QUrl("MyView.qml"));
Run Code Online (Sandbox Code Playgroud)

.

ApplicationWindow {
    visible: true
    width: 1280
    height: 720    

    BoxView {
        id: view
    }

    onClosing: {
        view.deleteView()
    }
}
Run Code Online (Sandbox Code Playgroud)


mab*_*abg 5

你可以在QQuickView上拦截close事件。为此,请创建一个派生类并覆盖事件方法:

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);
    }
};
Run Code Online (Sandbox Code Playgroud)

在主要,实例你的新类:

NewQuickView quickView(QUrl("MyView.qml"));
Run Code Online (Sandbox Code Playgroud)