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.
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.