如何将关键焦点传递给 QML 中的其他项目?
How to pass the key focus to the other item in QML?
这是我的 QML 文件中的代码:
main.qml
Rectangle {
id: window
color: "white"; width: 240; height: 150
Column {
anchors.centerIn: parent; spacing: 15
MyClickableWidget {
focus: true //set this MyWidget to receive the focus
color: "lightblue"
}
MyClickableWidget {
color: "palegreen"
}
}
}
MyClickableWidget.qml
FocusScope {
id: scope
//i try to set true instead of the mouse event
//focus: true
//FocusScope needs to bind to visual properties of the children
property alias color: rectangle.color
x: rectangle.x; y: rectangle.y
width: rectangle.width; height: rectangle.height
Rectangle {
id: rectangle
anchors.centerIn: parent
color: "lightsteelblue"; width: 175; height: 25; radius: 10; antialiasing: true
Text { id: label; anchors.centerIn: parent }
focus: true
Keys.onPressed: {
if (event.key == Qt.Key_A)
label.text = 'Key A was pressed'
else if (event.key == Qt.Key_B)
label.text = 'Key B was pressed'
else if (event.key == Qt.Key_C)
label.text = 'Key C was pressed'
}
}
MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } }
}
关于这段代码我有两个问题:
第一个。 第一个组件已设置 focus: true
。然后当按下键时,它会显示文本。但我不清楚为什么单击 MyClickableWidget
中的任何一个都会使其获得焦点而另一个小部件失去焦点?单击事件是否将焦点赋予组件?如果是,哪一部分将获得焦点(scope
或 rectangle
)?
另外,在我看来,如下所示的行是将scope.focus
设置为true
。所以,我注释掉这一行,在scope
中插入一行focus = true
。但是它不起作用,无法将关键焦点传递给其他项目。为什么?
// MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } }
结果是一样的。我不知道为什么代码需要这一行。
其次在focus scopes中,如果children有focus: true
,所有parent和root都会自动设置focus: true
?如果不在焦点范围内,结果是否相同?
为什么首先需要 FocusScope
?如果你摆脱它,你的代码可以大大简化。
需要知道的一件重要事情是,在 FocusScope
中,一次只能有一个项目获得焦点 。应用程序 window 的行为类似于 FocusScope
本身。为简单起见,如果某个项目获得焦点,则之前获得焦点的项目会自动失去焦点。
FocusRect.qml
Rectangle {
width: 175;
height: 25;
radius: 10;
Text { id: label; anchors.centerIn: parent }
Keys.onPressed: {
if (event.key == Qt.Key_A)
label.text = 'Key A was pressed'
else if (event.key == Qt.Key_B)
label.text = 'Key B was pressed'
else if (event.key == Qt.Key_C)
label.text = 'Key C was pressed'
}
MouseArea
{
anchors.fill: parent
onClicked: parent.forceActiveFocus()
}
}
main.qml
ApplicationWindow {
width: 960
height: 540
Column {
anchors.centerIn: parent;
spacing: 15
FocusRect {
focus: true //set this MyWidget to receive the focus
color: "lightblue"
}
FocusRect {
color: "palegreen"
}
}
}
这里的行为是直截了当的。项目必须具有 activeFocus 才能获取关键事件。对于将 activeFocus 设置为 true 的 Item,必须满足两个条件
- 项目本身的焦点 属性 设置为 true
- 其最近的 FocusScope 父级具有 activeFocus 或它没有 focusScope 父级,并且应用程序 window 具有活动焦点。
在这个简单的例子中,将 MyClickableWidget
的焦点设置为 true 也会将其 activeFocus 设置为 true(无父 FocusScope),使其能够获取 KeyEvents。
在回答您的第二个问题时,在 FocusScope
中,将项目的焦点设置为 true 不会产生副作用。但是,强制它获得 activeFocus(通过对其调用 forceActiveFocus()
)将使其所有 FocusScope 父级获得 activeFocus(因此将项目父层次结构中的所有 FocusScope 的焦点设置为 true)
相反,如果 FocusScope 获得活动焦点并且有一个子项的焦点设置为 true,则子项 activeFocus 也将设置为 true。
这是我的 QML 文件中的代码:
main.qml
Rectangle {
id: window
color: "white"; width: 240; height: 150
Column {
anchors.centerIn: parent; spacing: 15
MyClickableWidget {
focus: true //set this MyWidget to receive the focus
color: "lightblue"
}
MyClickableWidget {
color: "palegreen"
}
}
}
MyClickableWidget.qml
FocusScope {
id: scope
//i try to set true instead of the mouse event
//focus: true
//FocusScope needs to bind to visual properties of the children
property alias color: rectangle.color
x: rectangle.x; y: rectangle.y
width: rectangle.width; height: rectangle.height
Rectangle {
id: rectangle
anchors.centerIn: parent
color: "lightsteelblue"; width: 175; height: 25; radius: 10; antialiasing: true
Text { id: label; anchors.centerIn: parent }
focus: true
Keys.onPressed: {
if (event.key == Qt.Key_A)
label.text = 'Key A was pressed'
else if (event.key == Qt.Key_B)
label.text = 'Key B was pressed'
else if (event.key == Qt.Key_C)
label.text = 'Key C was pressed'
}
}
MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } }
}
关于这段代码我有两个问题:
第一个。 第一个组件已设置 focus: true
。然后当按下键时,它会显示文本。但我不清楚为什么单击 MyClickableWidget
中的任何一个都会使其获得焦点而另一个小部件失去焦点?单击事件是否将焦点赋予组件?如果是,哪一部分将获得焦点(scope
或 rectangle
)?
另外,在我看来,如下所示的行是将scope.focus
设置为true
。所以,我注释掉这一行,在scope
中插入一行focus = true
。但是它不起作用,无法将关键焦点传递给其他项目。为什么?
// MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } }
结果是一样的。我不知道为什么代码需要这一行。
其次在focus scopes中,如果children有focus: true
,所有parent和root都会自动设置focus: true
?如果不在焦点范围内,结果是否相同?
为什么首先需要 FocusScope
?如果你摆脱它,你的代码可以大大简化。
需要知道的一件重要事情是,在 FocusScope
中,一次只能有一个项目获得焦点 。应用程序 window 的行为类似于 FocusScope
本身。为简单起见,如果某个项目获得焦点,则之前获得焦点的项目会自动失去焦点。
FocusRect.qml
Rectangle {
width: 175;
height: 25;
radius: 10;
Text { id: label; anchors.centerIn: parent }
Keys.onPressed: {
if (event.key == Qt.Key_A)
label.text = 'Key A was pressed'
else if (event.key == Qt.Key_B)
label.text = 'Key B was pressed'
else if (event.key == Qt.Key_C)
label.text = 'Key C was pressed'
}
MouseArea
{
anchors.fill: parent
onClicked: parent.forceActiveFocus()
}
}
main.qml
ApplicationWindow {
width: 960
height: 540
Column {
anchors.centerIn: parent;
spacing: 15
FocusRect {
focus: true //set this MyWidget to receive the focus
color: "lightblue"
}
FocusRect {
color: "palegreen"
}
}
}
这里的行为是直截了当的。项目必须具有 activeFocus 才能获取关键事件。对于将 activeFocus 设置为 true 的 Item,必须满足两个条件
- 项目本身的焦点 属性 设置为 true
- 其最近的 FocusScope 父级具有 activeFocus 或它没有 focusScope 父级,并且应用程序 window 具有活动焦点。
在这个简单的例子中,将 MyClickableWidget
的焦点设置为 true 也会将其 activeFocus 设置为 true(无父 FocusScope),使其能够获取 KeyEvents。
在回答您的第二个问题时,在 FocusScope
中,将项目的焦点设置为 true 不会产生副作用。但是,强制它获得 activeFocus(通过对其调用 forceActiveFocus()
)将使其所有 FocusScope 父级获得 activeFocus(因此将项目父层次结构中的所有 FocusScope 的焦点设置为 true)
相反,如果 FocusScope 获得活动焦点并且有一个子项的焦点设置为 true,则子项 activeFocus 也将设置为 true。