Android backbutton
-
I'm making simple examples with Qt 5.1 for android, but i have noted that with the backbutton the app exit instead of come back at previous stack page. Will be it also in future version? I think that is very important to have native behaviour (without trick).
-
This is true, but I'll tell you alpha version 4.1 was better than qt5.1 for android, was more stable
-
Hi there. The back button functionality works nicely in the Qt 5.1 developer preview without need for any tricks and behaves "according to specification":http://developer.android.com/reference/android/app/Activity.html (scroll to onKeyDown method).
According to Android documentation, the back button event is delivered via Activity.onKeyUp() which is translated as QEvent::KeyRelease with key code Qt::Key_Back.
To prevent your app from quitting, you have to handle (accept) this event. For example, in QML you would do something like this:
@
Rectangle {
focus: true // important - otherwise we'll get no key eventsKeys.onReleased: { if (event.key == Qt.Key_Back) { console.log("Back button captured - wunderbar !") event.accepted = true } }
}
@If you want to handle it on C++ level, override keyReleaseEvent() of your main Window and do the same in there.
That being said, how you implement the "come back at previous stack page" is entirely up to you.
-
Thanks for explaining :) It is a bit odd that it somehow works its way to quit.
-
I managed to catch the android back button in QML:
@ApplicationWindow {
onClosing: {
close.accepted = false
if (contextMenuManager.menuVisible)
contextMenuManager.menuVisible = false
}
}@ -
Keys.onReleased catches the Android back button in some instances.
It doesn't seem to work with ListView though. focus must be directed somewhere where I haven't anticipated.
Here is a sample main.qml with a ListView, which does not catch the Android back button:
@
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1ApplicationWindow {
id: appWindow
visible: true
width: 640
height: 480
title: qsTr("Hello World")ListModel { id: longModel Component.onCompleted: { for ( var i=1; i<=100; i++ ) append({"testName": i}) } } ListView { anchors.fill: parent id: listView model: longModel delegate: Rectangle { height: 80 width: parent.width Text { id: textComponent text: testName } Keys.onReleased: { if (event.matches(StandardKey.Back)) { console.log("back caught by delegate"); event.accepted = true; } } } focus: true Keys.onReleased: { if (event.matches(StandardKey.Back)) { console.log("back caught by listview"); event.accepted = true; } } }
}
@ -
Keys.onReleased catches the Android back button in some instances.
It doesn't seem to work with ListView though. focus must be directed somewhere where I haven't anticipated.
Here is a sample main.qml with a ListView, which does not catch the Android back button:
@
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1ApplicationWindow {
id: appWindow
visible: true
width: 640
height: 480
title: qsTr("Hello World")ListModel { id: longModel Component.onCompleted: { for ( var i=1; i<=100; i++ ) append({"testName": i}) } } ListView { anchors.fill: parent id: listView model: longModel delegate: Rectangle { height: 80 width: parent.width Text { id: textComponent text: testName } Keys.onReleased: { if (event.matches(StandardKey.Back)) { console.log("back caught by delegate"); event.accepted = true; } } } focus: true Keys.onReleased: { if (event.matches(StandardKey.Back)) { console.log("back caught by listview"); event.accepted = true; } } }
}
@ -
Can someone post a C++ version of this? I have tried to convert it and I am still not seeing the back key.
Never mind.... Here is a C++ version I was able to get to work....
@
#include <QDebug>// regular MainWindow stuff...
void MainWindow::keyPressEvent (QKeyEvent* event) {
if (event->key () == Qt::Key_Back)
qDebug () << "<<keyPressEvent>> " <<
"[[Back button]]";
else if (event->key () == Qt::Key_HomePage)
qDebug () << "<<keyPressEvent>> " <<
"[[Home button]]";
else if (event->key () == Qt::Key_Menu)
qDebug () << "<<keyPressEvent>> " <<
"[[Menu button]]";
else if (event->key () == Qt::Key_unknown)
qDebug () << "<<keyPressEvent>> " <<
"[[Unknown button]]";
event->accept ();
}
@ -
Can someone post a C++ version of this? I have tried to convert it and I am still not seeing the back key.
Never mind.... Here is a C++ version I was able to get to work....
@
#include <QDebug>// regular MainWindow stuff...
void MainWindow::keyPressEvent (QKeyEvent* event) {
if (event->key () == Qt::Key_Back)
qDebug () << "<<keyPressEvent>> " <<
"[[Back button]]";
else if (event->key () == Qt::Key_HomePage)
qDebug () << "<<keyPressEvent>> " <<
"[[Home button]]";
else if (event->key () == Qt::Key_Menu)
qDebug () << "<<keyPressEvent>> " <<
"[[Menu button]]";
else if (event->key () == Qt::Key_unknown)
qDebug () << "<<keyPressEvent>> " <<
"[[Unknown button]]";
event->accept ();
}
@ -
on Android, I did this:
void MainWindow::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Back) qDebug() << "[[Back button]]"; else if (event->key() == Qt::Key_Menu) qDebug() << "[[Menu button]]"; else if (event->key() == Qt::Key_TopMenu) qDebug() << "[[Top menu button]]"; else qDebug() << "[[some other button]]"; event->accept(); }
I get a debug message for the back button, but not for the menu button...I also tried Qt::Key_TopMenu, but still nothing
nor do I get the "some other button" debug message when the menu button is pressed, so this method is not even being called when I press the menu button
this message must be handled somewhere else
can anyone help?
Thanks
-
C++ code. Gives the desired/standard effect on Android. Use a QWidget with a QStackedLayout in the main window.
stackedLayout = new QStackedLayout; QWidget *c = new QWidget(); first = new FirstForm(this ); stackedLayout->addWidget( first ); c->setLayout( stackedLayout ); setCentralWidget( c );
Override the closeEvent in the header:
protected: void closeEvent(QCloseEvent *event);
Implement the code in the body:
void MainWindow::closeEvent(QCloseEvent *event) {
if( stackedLayout->currentIndex() > 0 ) { QWidget *top = stackedLayout->currentWidget(); stackedLayout->removeWidget( top ); event->ignore(); }
}
// QED
-
In Qt 5.4.2 this is what i use and it works fine:
ApplicationWindow {
....
onClosing: {
if (Qt.platform.os == "android") {
close.accepted = false;
if (stack.depth > 1) stack.pop();
}
}
}@uCampaign this is my enhanced version:
Window { //... onClosing: { if (Qt.platform.os === "android" || Qt.platform.os === "ios") { close.accepted = false; if (menu.isShown) menu.hide(); else if (stackView.depth > 1) stackView.pop(); else Qt.quit(); } } }
Thank you :)