Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

installEventFilter not working on PySide6



  • I'm trying a minimal example on eventFilter without success. Here's my code:

    import sys
    from pathlib import Path
    from PySide6.QtCore import QObject
    from PySide6.QtQml import QQmlApplicationEngine
    from PySide6.QtWidgets import QApplication
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
    
        engine = QQmlApplicationEngine()
        qml_path = Path(__file__)
        qml_file = qml_path.with_suffix('.qml')
        engine.load(qml_file)
        root_objects = engine.rootObjects()
        if not root_objects:
            sys.exit(-1)
    
        mainwindow = root_objects[0]
    
        class EventInspector(QObject):
            def eventFilter(self, obj, event):
                print('obj >>', obj)
                print('event >>', event)
                return QObject.eventFilter(obj, event)
    
        app.installEventFilter(EventInspector())
        sys.exit(app.exec())
    

    When I run this code on a QML window with a couple of controls nothing happens, not a single event is printed.

    I have tried to change line 26 for...

        mainwindow.installEventFilter(EventInspector())
    

    ...but nothing happens either. No event is captured by the filter in this case either. Am I misunderstanding how event filters are supposed to work in PySide6?



  • @EddieC
    I believe you are doing it correctly, but I know nothing about QML nor PySide6.

    I am a touch concerned about the lifetime of your EventInspector() as a parameter only. Will Python release this after the call? Try:

    eventInspector = EventInspector()
    app.installEventFilter(eventInspector)
    

    ? Otherwise what about knocking up a 4-line widgets application and trying it there, in case it's a QML issue?



  • @EddieC
    I believe you are doing it correctly, but I know nothing about QML nor PySide6.

    I am a touch concerned about the lifetime of your EventInspector() as a parameter only. Will Python release this after the call? Try:

    eventInspector = EventInspector()
    app.installEventFilter(eventInspector)
    

    ? Otherwise what about knocking up a 4-line widgets application and trying it there, in case it's a QML issue?



  • @JonB

    Bingo! That solves the problem, thank you!

    I am somewhat surprised that the internal reference from app to the eventInspector object is not enough to keep the object alive (as per the usual rules of Python's garbage collection). Either I missed the memo on references from Qt to Python being weakrefs, or this might be a bug on the API.



  • @EddieC
    Yes, I too am unsure why it does not keep a reference around, but do not know the rules/implementation.

    A little tip worth knowing for this kind of potential problem. There is a QObject::destroyed() signal on every QObject-derived object. If you slotted onto that from your EventInspector you would/should see it getting destroyed, and that would tell you that you needed to keep your own reference.


Log in to reply