How to determine when QML window closed.



  • I'm trying to determine when a QML window is closed from my c++ code.

    There is the closing(QQuickCloseEvent*) signal - which is a little broken, because I can't use the new signal/slots on it since QQuickCloseEvent is private - ANYWAYS.. This signal isn't reliable since I could theoretically cancel the close (and if there are multiple listeners, I have no idea which order my listener would be called). I tried to subclass QQuickWIndow, but there doesn't even seem to be any virtual methods - like onClose(). I've seen people mention setting DeleteOnClose flag and wait for destroyed() signal, but this only seems to apply to widgets apps.


  • Moderators

    Hi mulhaupt,

    a simple solution could be to use the visibilityChanged signal. This example works for me:

    // main.cpp 
    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QObject>
    #include "dings.h"
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        Dings dings;
        QObject* rootObj = engine.rootObjects().at(0);
        QObject::connect(rootObj, SIGNAL(dingdong()), &dings, SLOT(sayHello()));
        return app.exec();
    }
    
    // dings.h
    #ifndef DINGS_H
    #define DINGS_H
    #include <QObject>
    #include <QDebug>
    class Dings : public QObject
    {
        Q_OBJECT
    public:
        explicit Dings(QObject *parent = 0);
        ~Dings();
    public slots:
        void sayHello() const { qDebug() << "hello"; }
    };
    #endif // DINGS_H
    
    // dings.cpp
    #include "dings.h"
    
    Dings::Dings(QObject *parent) : QObject(parent)
    {
    }
    
    Dings::~Dings()
    {
    }
    
    // main.qml
    import QtQuick 2.4
    import QtQuick.Window 2.2
    
    Window {
        title: qsTr("Hello World")
        width: 640
        height: 480
        visible: true
    
        signal dingdong
    
        onVisibilityChanged: {
            if (visibility==Window.Hidden)
                dingdong()
        }
    }
    

    Cheers!
    Wieland

    P.S.: I haven't figured out how to format code properly in the new forum yet. Sorry for that ;-)


  • Moderators

    @Wieland put the code inside ``` (3 backticks)


  • Moderators

    @mulhaupt If you subclass QQuickWindow you can use eventFilter to track the events. You will need to installEventFilter for it first. Eg.

    //myqquickwindow.cpp
    bool MyWindow::eventFilter(QObject *o, QEvent *e)
    {
        if (e->type() == QEvent::Close)
        {
            qDebug() << "Closing";
            e->accept();
        }
        return QObject::eventFilter(o, e);
    }
    
    // And in constructor
    installEventFilter(this);
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.