Getting focus/activeFocus status from QML ListView
Solution 1
I think I found a workaround:
onActiveFocusChanged: { focusChanged(focus) }
This emits the focusChanged signal whenever the active focus changes. Using this, the property bindings (like color: parent.focus ? "red" : "#E6E6E6") work as well.
Full test code:
import QtQuick 1.1
FocusScope {
width: 960
height: 540
id: app
focus: true
FocusScope {
id: leftColumn
KeyNavigation.right: rightColumn
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.top: parent.top
width: 250
onActiveFocusChanged: { focusChanged(focus) }
Rectangle {
id: leftBackgroundColor
anchors.fill: parent
color: parent.focus ? "red" : "#E6E6E6"
ListView {
id: contactsList
interactive: true
anchors.fill: parent
focus: true
delegate: Text {
text: name
font.bold: activeFocus
}
model: ListModel {
ListElement { name: "Simon" }
ListElement { name: "Mary" }
ListElement { name: "Jack" }
ListElement { name: "Frank" }
}
}
}
}
FocusScope {
id: rightColumn
focus: true
KeyNavigation.left: leftColumn
anchors.left: leftColumn.right
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.top: parent.top
onActiveFocusChanged: { focusChanged(focus) }
Rectangle {
id: rightBackgroundColor
anchors.fill: parent
focus: true
color: activeFocus ? "red" : "#b3b3b3"
}
}
}
Solution 2
I know that this is an old question, but I think it still deserves a proper explanation, as the same model of focus is still used in QtQuick 2.
How can I check whether the ListView or one of it's children has focus?
The central problem here is that you appear to be a little confused about the meanings of the two focus properties (and that's understandable, it's a bit non-obvious).
To see if a FocusScope (or any of its children) has focus right now, you want to check the Item::activeFocus
property on it. This means "either I, or one of my children has focus right now", and it's recursively cleared from a FocusScope when focus is moved to another FocusScope.
On the other hand, Item::focus
is a request for focus, not information about the current state, so you should not be binding other values on it (e.g. color: foo.focus ? "black" : "red"
) to it, unless you want to check whether or not the item is capable of gaining focus at some point in the future, not whether it has focus right now.
That explains why you can have something with Item::focus
true, while it doesn't actually have focus -- it's not that the signal is missing, it's that you were misusing the property to mean something it isn't.
So, you want something like this:
Rectangle {
id: leftBackgroundColor
anchors.fill: parent
color: leftColumn.activeFocus ? "red" : "#E6E6E6"
}
...
Rectangle {
id: rightBackgroundColor
anchors.fill: parent
focus: true
color: rightColumn.activeFocus ? "red" : "#b3b3b3"
}
Simon Warta
Updated on June 04, 2022Comments
-
Simon Warta almost 2 years
I've a two column layout with a ListView in the left column. With the Left/Right Keys I can change focus between the two parts of the app.
The active focus of the left column is delegated to the ListView and from there straight to one of it's rows.
How can I check whether the ListView or one of it's children has focus?
import QtQuick 1.1 FocusScope { width: 960 height: 540 id: app focus: true FocusScope { id: leftColumn KeyNavigation.right: rightColumn anchors.bottom: parent.bottom anchors.left: parent.left anchors.top: parent.top width: 250 focus: true Rectangle { id: leftBackgroundColor anchors.fill: parent color: contactsList.activeFocus ? "red" : "#E6E6E6" ListView { id: contactsList interactive: true anchors.fill: parent focus: true delegate: Text { text: name font.bold: activeFocus } model: ListModel { ListElement { name: "Simon" } ListElement { name: "Mary" } ListElement { name: "Jack" } ListElement { name: "Frank" } } } } } FocusScope { id: rightColumn KeyNavigation.left: leftColumn anchors.left: leftColumn.right anchors.right: parent.right anchors.bottom: parent.bottom anchors.top: parent.top onFocusChanged: console.log("Right focus changed: " + focus + "/" + activeFocus) Rectangle { id: rightBackgroundColor anchors.fill: parent focus: true color: activeFocus ? "red" : "#b3b3b3" } } }