QML 几个具有活动焦点/键盘快捷键控制的项目
Posted
技术标签:
【中文标题】QML 几个具有活动焦点/键盘快捷键控制的项目【英文标题】:QML several items with active focus / keyboard shortcut control 【发布时间】:2015-08-26 09:02:30 【问题描述】:我正在尝试为我的 qml 应用程序实现键盘快捷键控制。我知道有可能使用 Action 元素来做到这一点,但我不想要那些必须使用的菜单和工具栏。
这就是为什么我用键盘事件来处理这个话题。为此,我需要让执行操作的元素成为焦点。但我的目标是全局快捷控制,所以理论上我需要关注所有有问题的元素。
我在文档中找到了FocusScope
类型,但我不确定这是否是我需要的。
这是否意味着嵌套FocusScopes
的焦点“滑动”到不是FocusScope
的最后一个元素并使用focus: true
手动获取焦点,因此只有最后一个元素保持焦点?还是幻灯片中所有获取焦点的元素都设置了activeFocus
属性?
这是正确的方法还是我需要其他方法?
【问题讨论】:
【参考方案1】:在我看来,Qt Quick 中的焦点是一团糟。它总是让我感到困惑,我最终用forceActiveFocus()
破解它。我推荐新的Shortcut
类型:
Shortcut
sequence: StandardKey.Quit
context: Qt.ApplicationShortcut
onActivated: Qt.quit()
使用context
属性,您可以选择是要将快捷方式应用于当前窗口还是整个应用程序。
这种类型的动机可以在comments of patch set 5中看到:
Shortcut 旨在取代 Action。以后想干掉后者是因为……
对比实际用户码:http://cutebin.fi/prwznhkbo 查看 BasicButton.qml 周围“动作”相关表达式的数量 恕我直言,整个概念不太适合移动/嵌入式或 QML动作是一个经常被要求的功能。现在他们有了它,常见的问题是“如何使用不同的图标/文本”或“如何知道触发动作的来源”。两者都与 Action 的唯一目的相矛盾,如果他们只是首先编写更简单的 QML 代码,就不会存在任何“问题”,如示例 sn-p 所示。 :)
显然,Action 最有用的部分是快捷方式功能。那些需要捷径的人对他们需要使用 Action 并不满意,因为“所有这些其他的东西是怎么回事,我只想要一个捷径”。
【讨论】:
嗯,看起来很有希望。谢谢你的好信息。 “我认为 Qt Quick 中的焦点是一团糟”,遗憾的是 链接失效了! @arennuit 我从 Gerrit 的更改中引用的链接?是的,不幸的是。 很公平。感谢收看。【参考方案2】:也许有不同的方法可以实现这一点,但我知道的方法如下。
这个想法是有一个Item
来控制您需要处理的关键事件。
我会用一个例子来解释自己。正如您将看到的,如果我们有输入小部件(即TextInput
),我们必须实现一种机制来将输入返回到我们的Item
,以便再次处理键盘事件。在本例中,Qt.Key_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;
编辑 #1: @Mitch 建议使用 Shortcut
QML 类型。如果你可以使用它(它从 Qt 5.5 开始可用),代码会略有不同。无论如何,在某些情况下,您还需要将焦点设置到主应用程序,具体取决于实现的快捷方式序列。例如,如果我们正在输入文本,Shift+Q
在此示例中不起作用。我们需要先按 Escape。
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;
【讨论】:
【参考方案3】:很像 Mitch,我发现 QML 中的焦点是一团糟,就像它的许多其他方面一样。
我最终实现了我自己的“主动焦点/选择”方案。基本上,我将项目指针列表保留为“活动选择”,我将键盘焦点固定在充当事件调度程序的单个项目上,并将键盘事件重定向到活动选择列表中的所有项目。我还是使用 QML 的MouseArea
来管理选中的项目。
【讨论】:
以上是关于QML 几个具有活动焦点/键盘快捷键控制的项目的主要内容,如果未能解决你的问题,请参考以下文章