catch Android back button from navigation bar
-
Hello,
I am trying to manage the back button action in QML, so I have tried:
Window { id: root width: 640 height: 480 visible: true title: qsTr("Hello World") Rectangle { id: main focus: true // important - otherwise we'll get no key events Component.onCompleted: main. forceActiveFocus() Keys.onReleased: { console.log("event key:", event.key); if (event.key == Qt.Key_Back) { console.log("Back button captured!"); event.accepted = true; } } } }
but it does not do anything, the back button kills the application, does not even console.log "event key".
so as far as I assume the back button in navigation bar is just hardware keyboard, then this shall work?
also, on the other hand i have made lots of manual modificaitons on my android emulator, so its possible i did disable this :D
can anyone try on real device please? or tell me if my approach is actually good?Thank you
-
Solution found...
in android manifest, in <application> i must deactivate enableOnBackInvokedCallback, so correct is:android:enableOnBackInvokedCallback="false"
from this point, all works as expected
seems as new thing from android 13 according to google search -
Hi
are you sure that the onReleased event is the one you need ?
have you tried other events like key pressed to see what happens ? -
release and pressed are all different signals, its possible that the uncaptured pressed key event is enough for the application to close
The way I do it in my applications is by intercepting the close event instead:
onClosing: { //Management for Android Back-Button if(Qt.platform.os === "android"){ close.accepted = false if(PageManager.pageIndex > 0) PageManager.pageIndex = 0 } }
but thats based on really old legacy code, so the key event route may be the more correct way to do it :D
-
@J-Hilk According to 6.7.3's Window documentation, your way is still the appropriate one to handle such case.
-
hmm very weird, i tried:
Window { id: root // Management for Android Back-Button onClosing: { console.log("debug1"); if (Qt.platform.os === "android" || Qt.platform.os === "ios") { console.log("debug2"); close.accepted = false; console.log("debug3"); } else { console.log("debug4"); close.accepted = true; } } }
and I got:
W WindowOnBackDispatcher: sendCancelIfRunning: isInProgress=falsecallback=android.app.Activity$$ExternalSyntheticLambda0@cd8e98f // thsi is OK behaviour for back button on Android, so all good D qml : : debug1 D qml : : debug2 W qt.qml.context: : qrc:/Main.qml:23:2 Parameter "close" is not declared. Injection of parameters into signal handlers is deprecated. Use JavaScript functions with formal parameters instead. // this is line with "onClosing: {" D qml : : debug3 // should this also be printed to console? its after close event
what do i do wrong?
-
and according to:
https://stackoverflow.com/questions/47175409/qml-asking-confirmation-before-closing-application (last post)
and https://www.direktembedded.com/qt5-to-qt6-qml-pyside-porting/the following still does NOT work :(
onClosing: function(close) { console.log("debug1"); if (Qt.platform.os === "android" || Qt.platform.os === "ios") { console.log("debug2"); close.accepted = false; console.log("debug3"); } else { console.log("debug4"); close.accepted = true; } }
W WindowOnBackDispatcher: sendCancelIfRunning: isInProgress=falsecallback=android.app.Activity$$ExternalSyntheticLambda0@cd303a8 D qml : : debug1 D qml : : debug2 D qml : : debug3
and closes anyway
-
writing
onClosing: (close) => // or function (close), they're equivalent { console.log ("closing window") ; close.accepted = false ; }
works fine, and I have to forcefully close the app. I've only tested on windows, not on android.
However Qt Creator pisses me of with an "Invalid property name 'onClosing'" error
Writing
onClosing: { console.log ("closing window") ; close.accepted = false ; }
works the same, I still have to forcefully quit, but produces me the same deprecation warning than you posted earlier.
At the origins of QtQuick, there had been criticism again the fact that slots didn't make their parameters explicit, making the parameters look like coming out of nowhere. Thus the newer syntax on your screenshot.
-
Solution found...
in android manifest, in <application> i must deactivate enableOnBackInvokedCallback, so correct is:android:enableOnBackInvokedCallback="false"
from this point, all works as expected
seems as new thing from android 13 according to google search -