Reputation: 2118
I have a UI where clicking on a control selects it and deselects any other control that is currently selected. It worked great until I loaded part of the UI into a Loader.
Now if I select an element on the loader while something outside the loader is selected, focus is correctly taken away from the outside control and given to the control on the Loader. But re-selecting the outside control does not take focus away from the control on the loader like it should.
I use forceActiveFocus()
to set focus where it is supposed to be. Only one item can have active focus so when you call forceActiveFocus()
on an element, it gets focus and whatever had focus loses it.
I wrote a small sample project that shows this behavior. When it opens, you see a Windows split into to two halves; the yellow half is a component in a Loader. Nothing is selected. Clicking a side will set focus to that side, either the parent Item or the Item in the Loader.
If you click the left half, it shows focused. This is exactly as expected.
If you click the right half, it shows focus and removes focus from the left half, again, this is exactly as expected.
But now if you click the exposed parent Item's side, it gets focus as expected, but the component in the Loader still shows that it has focus!
Clicking into the right half will correctly force focus to it and remove focus from the left half, but how to remove focus from the right half when clicking on the left half?
This Qt 5.6 code will reproduce the behavior:
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
visible: true
Item {
id: item
anchors.fill: parent
Text {
text: 'Focused'
font.bold: true
visible: parent.focus // incorrect; must use parent.activeFocus
}
MouseArea {
anchors.fill: parent
onClicked: item.forceActiveFocus()
}
Text {
text: 'Parent Item'
anchors.centerIn: parent
}
Loader {
id: loader
anchors {
left: parent.horizontalCenter; right: parent.right
top: parent.top; bottom: parent.bottom
}
sourceComponent: rect
opacity: .8
}
Text {
anchors.centerIn: loader
text: 'The\nLoader'
}
}
Component {
id: rect
Rectangle {
color: 'yellow'
Text {
text: 'Focused'
font.bold: true
visible: parent.focus // incorrect; must use parent.activeFocus
}
MouseArea {
anchors.fill: parent
onClicked: parent.forceActiveFocus()
}
}
}
}
Upvotes: 1
Views: 5201
Reputation: 2118
Use the activeFocus
property instead of the focus
property to determine whether or not an element has active focus. I am not sure why focus
worked so well before, but using it to detect active focus was a defective approach and destined to fail.
Upvotes: 4