Search code examples
qtpython-3.xqmlsignals-slotspyqt5

How to close Pyqt5 program from QML?


I started a project in Qt Creator initially with a C++ backend, but then switched it to use PyQt5. I have a main.qml, where when I press a button called Exit, I call Qt.quit().

However, I get a General Message stating: Signal QQmlEngine::quit() emitted, but no receivers connected to handle it.

My question is, how do I receive this signal and handle it?

Code:

main.py:

import sys
import PyQt5

from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5 import QtQml
from PyQt5.QtCore import QObject pyqtSignal


class DestinyManager,(QtGui.QGuiApplication):
    """the app self"""
    def __init__(self, argv):
        super(DestinyManager, self).__init__(argv)

    # Define a new signal called 'trigger' that has no arguments.
    trigger = pyqtSignal()

    def connect_and_emit_trigger(self):
        # Connect the trigger signal to a slot.
        self.trigger.connect(self.handle_trigger)
        self.menuItem_Exit.clicked.connect(self.close)
        # Emit the signal.
        self.trigger.emit()

    def handle_trigger(self):
        # Show that the slot has been called.
        print("trigger signal received")

def main(argv):
    app = DestinyManager(sys.argv)
    engine = QtQml.QQmlEngine(app)
    component = QtQml.QQmlComponent(engine)
    component.loadUrl(QtCore.QUrl("exit.qml"))
    topLevel = component.create()
    if topLevel is not None:
        topLevel.show()
    else:
        for err in component.errors():
            print(err.toString())
    app.exec()

if __name__ == '__main__':
    QObject,main(sys.argv)

Exit.qml:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2

Window {

    Button {
    id: btn_Exit
    text: "Exit"

    onClicked: Qt.quit();

    }
}

Solution

  • There are a few syntax errors in the python script, but ignoring those, the code can be made to work like this:

        def main(argv):
            app = DestinyManager(sys.argv)
            engine = QtQml.QQmlEngine(app)
            engine.quit.connect(app.quit)
            ...
    

    Which is to say, you simply need to connect the qml quit signal to an appropriate slot in your python script.