Search code examples
pythonpyqtqmlpyqt5keyevent

How to generate KeyEvents in QML application?


I am using PyQt5 together with QML to create an application. I need to be able to simulate keyboard board events either from PyQT to my QML objects or alternatively from QML itself.

I'm using a QQmlApplicationEngine to load my QML and I am using a "back end" QObject in Python to connect to signals and slots in QML.

app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
backend = Backend()
engine.rootContext().setContextProperty("backend", backend)
engine.load('./qml/main.qml')
app.setEngine(engine)

Later on I try to send a key event:

app.sendEvent(engine.rootObjects()[0].focusObject(), QKeyEvent(QEvent.KeyRelease, Qt.Key_Down, Qt.NoModifier))

In my QML I have a list view which has the focus. If I press the up and down keys on my keyboard the focused item in the list changes as expected. However, when I try sending a key event using the code above, the list view does not react.

The engine.rootObjects()[0] is a QObject when printed.

QML snippet:

ApplicationWindow {
    // list model here
    // list delegate here
    ListView {
        id: menuView
        anchors.fill: parent
        focus: true
        model: menuModel
        delegate: menuDelegate
        keyNavigationEnabled: true
        keyNavigationWraps: true
   }
}

Alternatively, I wondered if it is possible to generate a key event from within QML itself by interacting with activeFocusItem of the ApplicationWindow object? I haven't been able to get this to work either.


Solution

  • This did the trick in the end after looking at how the QtGamepad class generates key events:

    QGuiApplication.sendEvent(app.focusWindow(), QKeyEvent(QEvent.KeyPress, Qt.Key_Down, Qt.NoModifier))
    

    Now my QML application responds in the same way as if the user had pressed a key.