以下是我的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
会使焦点集中而另一个小部件失去焦点? click事件是否将焦点放在组件上?如果是,哪个部分将获得焦点(scope
或rectangle
)?
此外,在我看来,以下显示的行是将scope.focus
设置为true
。所以,我注释掉这一行,在focus = true
中插入一行scope
。但是它不起作用,无法将关键焦点传递给其他项目。为什么呢?
// MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } }
结果是一样的。我不知道为什么代码需要这一行。
第二。在焦点范围内,如果孩子拥有focus: true
,则会自动设置所有父和根focus: true
?如果不在焦点范围内,结果是否相同?
答案 0 :(得分:1)
为什么首先需要FocusScope
?如果你摆脱它,你的代码可以大大简化。
重要的是要知道,在FocusScope
内,一次只能有一个项目。应用程序窗口的行为类似于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,必须满足两个条件
在这个简单的例子中,将MyClickableWidget
的焦点设置为true也会将其activeFocus设置为true(无父FocusScope),使其能够获取KeyEvents。
在回答您的第二个问题时,在FocusScope
内,将项目的焦点设置为true将不会产生任何副作用。但是,强制它获得activeFocus(通过在其上调用forceActiveFocus()
)将使其所有FocusScope父项获得activeFocus(并因此将焦点设置为项目的父级层次结构中所有FocusScope的true)
相反,如果FocusScope获得活动焦点并将焦点设置为true的子节点,则子activeFocus也将设置为true。