Android后退按钮按下不会触发按键。已发布的qml

时间:2014-09-22 07:24:56

标签: android qt qml qt5 qtquick2

我正在Qt5.3和Qtquick2.1中创建一个程序。我试图使用Keys.onReleased在我的代码中捕获按钮上的按钮。但是这个事件没有被触发。此外,我已将项目焦点设置为true。但仍然没有成功。这是代码示例

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

这里loadPatwin是按下某个其他qml中定义的按钮时调用的函数。并加载一个新的qml。但在那之后,当我按下Android上的后退按钮时,应用程序会关闭,它甚至不会打印出来#34;返回"在日志中。我在这里做错了什么建议吗?

提前致谢。

5 个答案:

答案 0 :(得分:15)

在qt quick(Qt5.1及更高版本)ApplicationWindowWindow中,当用户触摸android中的后退按钮时,都会发出closing信号。 您可以简单地实现onClosing处理程序并将close参数设置为false。以下是如何做到这一点:

onClosing: {
    close.accepted = false
}

通过这个处理程序,您可以轻松管理Android设备的后退按钮。它不需要任何额外的许可。例如,假设您有一个StackView来管理GUI。您可以编写这些代码行,然后您的应用程序就像本机Android应用程序一样:

onClosing: {
        if(stack.depth > 1){
            close.accepted = false
            stack.pop();
        }else{
            return;
        }
    }

答案 1 :(得分:5)

通过在项目加载完成后添加“forceActiveFocus()”,它对我有用。

在你的例子中,我会把它放在开头。像这样:

Rectangle
{
    id: main2
    focus: true

    Component.onCompleted: {
        main2.forceActiveFocus()
    }

答案 2 :(得分:1)

我不知道这是否是一个很好的例子,但我曾经从QGuiApplication创建自己的GuiApplication类子类

#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

这是针对cpp代码

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

对于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();
}

最后是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")
    }
}

答案 3 :(得分:0)

我自己刚刚偶然发现了这个问题,但是处理 closingWindowApplicationWindows 信号的建议解决方案与其说是解决方案,不如说是一种变通方法。虽然它可能适用于 Android,但是当您实际上想要关闭窗口(例如,按窗口标题上的“x”按钮)时,任何跨平台应用程序都会使用“后退”按钮处理吧)

为了正确地做到这一点,我们必须记住 QtQuick 中的关键事件处理是如何发生的:带有 activeFocus 的项目首先获得事件。如果它不处理该事件,则将其传播到它的 parent 项。这一直持续到它到达根项目。关键在于:WindowApplicationWindow 是最外层的对象,但它们不是基于 ItemItem 实际上是 { {1}}。您需要在此处安装 Window::contentItem 处理程序以接收所有未处理的按键事件,包括 Back 按钮按下。不幸的是,附加属性不适用于只读的对象类型属性,因此我们必须在 Keys 中强制执行此操作:

onCompleted

答案 4 :(得分:-1)

在QML中===是布尔比较

而不是(event.key === Qt.Key_Back)

你应该使用(event.key == Qt.Key_Back){