QtQuick:如何覆盖窗口关闭事件?
Posted
技术标签:
【中文标题】QtQuick:如何覆盖窗口关闭事件?【英文标题】:QtQuick: how to override window close event? 【发布时间】:2015-10-16 13:53:44 【问题描述】:我在 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();
而 MyView.qml 看起来像这样:
import QtQuick 2.1
import QtQuick.Window 2.1
import com.my.stuff 1.0
Item VeryVeryImportantItem
id : veryVeryImportantItem
...
而VeryVeryImportantItem.h如下:
#include <QtQuick/QQuickItem>
class VeryVeryImportantItem : public QQuickItem
Q_OBJECT
public:
Q_INVOKABLE void cleanup();
...
;
现在问题来了。 如何在我的根窗口/视图上拦截关闭事件,调用 VeryVeryImportantItem::cleanup();并且只有在那之后关闭应用程序?
我现在发现的是 QQuickItem::window()
可以给我指向我需要的窗口的指针,并且窗口有信号 QQuickWindow::closing(QQuickCloseEvent *);
并且理论上我可以通过操作给定的来防止窗口关闭QQuickCloseEvent
对象。 但它不是公开的,我无权访问它的方法!
好的。另一种方法可能是我可以从 QML 做类似的事情。 QML 类型QWindow
具有closing(CloseEvent)
信号,如果我在与其连接的插槽中设置CloseEvent.accepted
false,这将阻止窗口立即关闭并使我能够调用veryVeryImportantItem.cleanup()
方法。但是我有另一个问题:如果我不是在 QML 中而是在 C++ 启动代码中创建它,我如何获得对我的根窗口的引用。
我想这是很常见的情况,显然应该有一个明确的方法来处理这个问题,但我已经用谷歌搜索了大约四个小时,仍然没有找到任何合适的解释。
【问题讨论】:
VeryVeryImportantItem 析构函数在您关闭窗口时被调用。您可以在这里进行任何清理。 嗯,我知道。但这不适合我的情况。我的架构需要一些信号交换才能完成清理。 【参考方案1】:我想这是很常见的情况,显然应该 是一个明确的方式来处理这个
是的,可以这么说。
最简单的做法是切换到使用 QQmlApplicationEngine
并在 QML 端使用 ApplicationWindow
作为根组件。
然后您可以简单地使用onClosing
信号处理程序来运行您的清理。我有一个类似的场景,如果在调用清理之前关闭应用程序会崩溃,而这种方法完美无缺。
//main.cpp
QQmlApplicationEngine engine;
engine.load(QUrl("MyView.qml"));
.
ApplicationWindow
visible: true
width: 1280
height: 720
BoxView
id: view
onClosing:
view.deleteView()
【讨论】:
如何才能延迟关闭诸如“你确定...?”之类的问题。使用模态Dialog
?如果没有额外的布尔标志属性,在命令式风格中似乎是不可能的。
@Orient - 只需添加一个property bool canExit
,然后根据您的要求在关闭事件中添加close.accepted = true or false
。【参考方案2】:
您可以在 QQuickView 上拦截关闭事件。为此,请创建一个派生类并覆盖事件方法:
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);
;
在 main 上,实例化你的新类:
NewQuickView quickView(QUrl("MyView.qml"));
【讨论】:
以上是关于QtQuick:如何覆盖窗口关闭事件?的主要内容,如果未能解决你的问题,请参考以下文章