Qt QML具有活动焦点/键盘快捷键控制的多个项目

Qt QML具有活动焦点/键盘快捷键控制的多个项目,qt,qml,Qt,Qml,我正在尝试为我的qml应用程序实现一个键盘快捷键控件。我知道有可能用一个动作元素来实现这一点,但我不希望菜单和工具栏被强制使用。 这就是为什么我要用键盘事件来讨论这个话题。为此,我需要让执行操作的元素处于焦点位置。但我的目标是一个全局快捷控制,所以理论上我需要把所有有问题的元素都集中起来。 我在文档中找到了类型,但我不确定这是否是我需要的。 这是否意味着嵌套的FocusScope的焦点“滑动”到不是FocusScope的最后一个元素,并使用focus:true手动获取焦点,因此只有最后一个元素保

我正在尝试为我的qml应用程序实现一个键盘快捷键控件。我知道有可能用一个动作元素来实现这一点,但我不希望菜单和工具栏被强制使用。 这就是为什么我要用键盘事件来讨论这个话题。为此,我需要让执行操作的元素处于焦点位置。但我的目标是一个全局快捷控制,所以理论上我需要把所有有问题的元素都集中起来。 我在文档中找到了类型,但我不确定这是否是我需要的。 这是否意味着嵌套的
FocusScope
的焦点“滑动”到不是
FocusScope
的最后一个元素,并使用
focus:true
手动获取焦点,因此只有最后一个元素保持焦点?或者幻灯片中所有获取焦点的元素是否都设置了
activeFocus
属性


这是正确的方法还是我需要其他方法?

可能有不同的方法来实现这一点,但我知道的方法如下

这个想法是要有一个
,它控制您需要处理的关键事件

我将用一个例子来解释我自己。如您所见,如果我们有输入小部件(即
TextInput
),我们必须实现一种机制,将输入返回到
,以便再次处理键盘事件。在本例中,将使用
Qt.Key\u Escape
键将焦点设置回原位

import QtQuick 2.4
import QtQuick.Controls 1.3

ApplicationWindow {
    id: mainwindow
    title: qsTr("Hello")
    width: 640
    height: 480
    visible: true

    Item {
        anchors.fill: parent
        focus: true

        Keys.onPressed: {
            if ( (event.key === Qt.Key_Q) && (event.modifiers & Qt.ShiftModifier) ) {
                rect.blue()
            } else if ( (event.key === Qt.Key_W) && (event.modifiers & Qt.AltModifier) ) {
                rect.red()
            } else if ( (event.key === Qt.Key_E) && (event.modifiers & Qt.AltModifier) ) {
                text.text = 'Key Alt+E was pressed'
            }
        }

        Rectangle{
            id: rect
            width: 100
            height: 100
            color: "black"

            function blue() {color = "blue"}
            function red() {color = "red"}
        }

        Text {
            id: text
            anchors.centerIn: parent
            font.pointSize: 20
        }

        TextInput {
            id: textinput
            anchors.top: text.bottom
            text: "sample text"

            Keys.onPressed: {
                if (event.key === Qt.Key_Escape) {
                    console.log('Key Escape was pressed');
                    parent.focus = true;
                }
            }
        }
    }
}
Edit#1:@Mitch建议使用
快捷方式
QML类型。如果您可以使用它(从Qt5.5开始提供),代码将略有不同。无论如何,在某些情况下,您还需要将焦点设置为主应用程序,具体取决于实现的快捷方式序列。例如,如果我们键入文本,
Shift+Q
在本例中无效。我们得先按一下逃生键

import QtQuick 2.5
import QtQuick.Controls 1.3

ApplicationWindow {
    id: mainwindow
    title: qsTr("Hello")
    width: 640
    height: 480
    visible: true

    Shortcut {
            sequence: "Shift+Q"
            onActivated: rect.blue()
            context: Qt.ApplicationShortcut
    }

    Shortcut {
            sequence: "Alt+W"
            onActivated: rect.red()
            context: Qt.ApplicationShortcut
    }

    Shortcut {
            sequence: "Alt+E"
            onActivated: text.text = 'Key Alt+E was pressed'
            context: Qt.ApplicationShortcut
    }

    Item {
        anchors.fill: parent

        Rectangle{
            id: rect
            width: 100
            height: 100
            color: "black"

            function blue() {color = "blue"}
            function red() {color = "red"}
        }

        Text {
            id: text
            anchors.centerIn: parent
            font.pointSize: 20
        }

        TextInput {
            id: textinput
            anchors.top: text.bottom
            text: "sample text"

            Keys.onPressed: {
                if (event.key === Qt.Key_Escape) {
                    console.log('Key Escape was pressed');
                    parent.focus = true;
                }
            }
        }
    }
}

在我看来,Qt Quick中的焦点是一团混乱。它总是让我感到困惑,我最终用
forceActiveFocus()
来破解它。我推荐新类型:

使用该属性,可以选择是将快捷方式应用于当前窗口还是整个应用程序

这种类型的动机可以从以下方面看出:

捷径旨在取代行动。我想在将来杀死后者,因为

  • 比较实际用户代码:
  • 查看BasicButton.qml中与“操作”相关的表达式的数量
  • IMHO整个概念不太适合移动/嵌入式或QML
行动是一个经常要求的功能。现在,他们有了它,常见的问题是“如何使用不同的图标/文本”或“如何知道触发动作的来源”。这两者都与操作的唯一目的相矛盾,如果他们首先只编写更简单的QML代码,那么这两个“问题”都不存在,如示例片段所示:

显然,操作最有用的部分是快捷功能。那些需要捷径的人并不高兴他们需要采取行动,因为“其他东西怎么了,我只想要一条捷径”


和Mitch一样,我发现QML中的focus也是一团糟,就像它的许多其他方面一样


我最终实施了自己的“主动聚焦/选择”计划。基本上,我保留一个项目指针列表作为我的“活动选择”,我将键盘焦点固定在单个项目上,充当事件调度器,它将键盘事件重定向到活动选择列表中的所有项目。我仍然使用QML的
MouseArea
来管理所选的项目。

嗯,这看起来很有希望。感谢您提供的好信息。“在我看来,Qt Quick中的焦点是一团混乱”遗憾的是,链接已经死了@这是我从Gerrit的变化中引用的链接吗?是的,不幸的是,这很公平。谢谢收看。
Shortcut {
    sequence: StandardKey.Quit
    context: Qt.ApplicationShortcut
    onActivated: Qt.quit()
}