I am creating a program in Qt5.3 and Qtquick2.1. I am trying to capture back button press on android in my code using Keys.onReleased. But that event is not getting triggered. Also I have set the item focus to true. But still no success. Here is the code sample
import QtQuick 2.1
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.1
Rectangle
{
id: main2
focus: true
width: Screen.Width
height: Screen.Height
Keys.enabled: true
Keys.priority: Keys.BeforeItem
property string load_page: ""
signal deskConnected()
Loader{
id: pageloader
anchors.fill: parent
source: "qrc:/qml/resources/Firstpage.qml"
}
onDeskConnected: {
pageloader.item.onDeskConnected()
}
function loadPatwin(){
pageloader.source = "qrc:/qml/resources/Secondpage.qml";
}
Keys.onReleased: {
console.log("back");
if (event.key === Qt.Key_Back) {
event.accepted=true;
}
}
}
Here loadPatwin is the function which gets called on pressing a button which is defined in some other qml. And loads a new qml. But after that when I am pressing the back button on android, the app gets closed and it doesn't print even "back" in the logs. Any suggestions what I am doing wrong here?
Thanks in advance.
In qt quick (Qt5.1 and later) the ApplicationWindow
and Window
, both have a closing
signal that is emitted when the user touches the back button in android.
You can simply implement an onClosing handler and set the close parameter to false. Here is how to do it:
onClosing: {
close.accepted = false
}
By this handler you can easily manage the back button of android device. It does not need any extra permission. For example suppose you have a StackView to manage the GUI. You can write these lines of code, Then your application behaves as like as a native android app:
onClosing: {
if(stack.depth > 1){
close.accepted = false
stack.pop();
}else{
return;
}
}
It works for me by adding "forceActiveFocus()" after the item has completed loading.
In your example I would put it at the beginning. Like this:
Rectangle
{
id: main2
focus: true
Component.onCompleted: {
main2.forceActiveFocus()
}
I don't know whether this is a good example, but I used to create my own GuiApplication class subclassing from QGuiApplication
#ifndef GUIAPPLICATION_H
#define GUIAPPLICATION_H
#include <QGuiApplication>
class GuiApplication : public QGuiApplication
{
Q_OBJECT
public:
#ifdef Q_QDOC
explicit GuiApplication(int &argc, char **argv);
#else
explicit GuiApplication(int &argc, char **argv, int = ApplicationFlags);
#endif
bool notify(QObject *receiver, QEvent *event);
signals:
void back();
};
#endif // GUIAPPLICATION_H
This is for cpp codes
#include "guiapplication.h"
#include <QDebug>
GuiApplication::GuiApplication(int &argc, char **argv, int) :
QGuiApplication(argc, argv)
{
}
bool GuiApplication::notify(QObject *receiver, QEvent *event)
{
// to intercept android's back button
#ifdef Q_OS_ANDROID
if(event->type() == QEvent::Close) {
emit back();
return false;
}
else {
return QGuiApplication::notify(receiver,event);
}
#else
return QGuiApplication::notify(receiver,event);
#endif
}
For main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "guiapplication.h"
int main(int argc, char *argv[])
{
// QGuiApplication app(argc, argv);
GuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QQmlContext *rootContext = engine.rootContext();
rootContext->setContextProperty("GUI", &app);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
and finally for main.qml
import QtQuick 2.3
import QtQuick.Controls 1.2
ApplicationWindow {
id: applicationWindow
visible: true
width: 360
height: 360
Connections {
target: GUI
onBack: console.log("back")
}
}
I've just stumbled upon this problem myself, but the proposed solution of handling the closing
signal of Window
or ApplicationWindows
is more of a workaround than a solution. While it might work fine for Android, any cross-platform application will then employ "back"-button handling when you actually want to close the window (e.g. press the the "x" button on the window title bar)
To do this correctly, we have to keep in mind how key event handling in QtQuick happens: The item with activeFocus
gets the event first. If it doesn't handle the event, it is propagated to it's parent
item. This goes on until it reaches the root item. Here's the crux: Window
or ApplicationWindow
are the outermost object, but they're not Item
-based! The root Item
is actually Window::contentItem
. This is where you need to install a Keys
handler to receive all non-handled key events, including Back
button presses. Unfortunately, attached properties don't work for read-only object-typed properties, so we have to do this imperatively in onCompleted
:
ApplicationWindow {
id: window
Component.onCompleted: {
// Connect to `released` signal and dispatch to `back()`
contentItem.Keys.released.connect(function(event) {
if (event.key === Qt.Key_Back) {
event.accepted = true
window.back()
}
})
}
function back() {
// Back button handling goes here
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With