Android back button press doesn't trigger keys

2019-02-22 06:03发布

问题:

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.

回答1:

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;
        }
    }


回答2:

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()
    }


回答3:

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")
    }
}


回答4:

In QML === is boolean comparison

So instead of (event.key === Qt.Key_Back)

You should use (event.key == Qt.Key_Back) {