Reputation: 285
Here are the code in my QML files:
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 } }
}
I have two question about this code:
First. The first component have been set focus: true
. Then when press key, it will show the text. But I am not clear that why clicking either MyClickableWidget
gives it focus and the other widget loses the focus? Does the click event give the focus to the component? If yes, which part will get the focus (scope
or rectangle
)?
Also, in my opinion, the line showed as following is to set scope.focus
to true
. So, I comment out this line, the insert a line focus = true
in the scope
. However it doesn't work, can not pass the key focus to the other item. Why?
// MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } }
The result is the same. I don't know why the code need this line.
Second. In focus scopes, if the children have the focus: true
, all parent and root will automatically be set focus: true
? if not in focus scopes, is the same result?
Upvotes: 2
Views: 6505
Reputation: 5326
Why do you need a FocusScope
in the first place? Your code can be greatly simplified if you get rid of it.
An important thing to know is that within a FocusScope
, only one item at a time can have focus. The application window behaves like a FocusScope
itself. To keep it simple, if an item gains focus, the item that previously had focus automatically loses it.
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"
}
}
}
The behavior here is stragihtforward. An item must have activeFocus to get key events. For an Item to have activeFocus set to true, two condition must be met
In this simple example, setting the focus of MyClickableWidget
to true will also set its activeFocus to true (no parent FocusScope), making it able to get KeyEvents.
In answer to your second question, within a FocusScope
, setting an item's focus to true will have no side effects. However, forcing it to gain activeFocus (by calling forceActiveFocus()
on it) will make all its FocusScope parents gain activeFocus (and consequently set focus to true for all FocusScope in the item's parent hierarchy)
Conversely, if a FocusScope gains active focus and have a child with focus set to true, the child activeFocus will also be set to true.
Upvotes: 3