Рассмотрим следующую программу QML, состоящую из двух файлов.
Файл main.qml :
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
width: 600
height: 600
visible: true
FocusScope {
property string name: "FocusScope"
Column {
MyRectangle {
id: rectA
name: "A"
}
MyRectangle {
name: "B"
}
MyRectangle {
id: rectC
name: "C"
}
MyRectangle {
id: rectD
name: "D"
}
MyRectangle {
name: "E"
}
}
}
onActiveFocusItemChanged: {
console.log("active focus changed to: " + activeFocusItem.name)
}
Component.onCompleted: {
rectA.forceActiveFocus()
}
}
Где MyRectangle
определено в файле MyRectangle.qml :
import QtQuick 2.6
Rectangle {
property string name
width: 50
height: 50
color: enabled ? (focus ? "red" : "black") : "lightgrey"
activeFocusOnTab: true
function enableWithActiveFocus(enabled)
{
if (enabled === this.enabled) {
return
}
if (enabled) {
this.enabled = true
return
}
if (activeFocusItem === this) {
nextItemInFocusChain(true).forceActiveFocus()
}
this.enabled = false
}
Text {
anchors.centerIn: parent
color: "white"
text: name
}
Keys.onReturnPressed: {
rectC.enableWithActiveFocus(!rectC.enabled)
}
}
Эта программа позволяет перемещаться между пятью прямоугольниками с помощью клавиш Tab и BackTab (Shift + Tab). «Навигация» означает «изменить активный фокус» - прямоугольник с активным фокусом выделяется красным. Можно также нажать клавишу Enter, чтобы отключить или включить rectC
(третий прямоугольник) - отключено rectC
становится серым.
Наиболее интересным является случай, когда кто-то перемещает активный фокус на rectC
, а затем делает это отключено. Что должно произойти с активным фокусом в этом случае? Я хочу, чтобы в этом случае активный фокус передавался следующему прямоугольнику в цепочке фокусировки, т.е. rectD
. Однако QML работает так, что если мы просто изменим свойство enabled
элемента, имеющего активный фокус, на false
(вызывая, например, rectC.enabled = false
), этот элемент сначала теряет активный фокус, а затем становится отключенным ( в данном примере потерянный активный фокус будет получен группой FocusScope
). Когда активный фокус теряется элементом, невозможно знать, какой элемент следующий за этим элементом в цепочке фокусировки. И это проблема!
Вот почему я реализовал функцию enableWithActiveFocus()
и использую только ее, чтобы сделать прямоугольник отключенным или включенным. Когда кто-то делает прямоугольник с активным фокусом отключенным с помощью этой функции, функция сначала перемещает активный фокус на элемент, следующий за цепочкой фокусировки, а затем отключает начальный элемент. Без потери активного фокуса!
Мой вопрос: Есть ли возможность каким-либо образом реализовать то же поведение (передача активного фокуса следующему элементу, когда текущий элемент имеет активный фокус и отключен ) с помощью простого связывания свойств QML? Например, я хочу иметь что-то вроде этого:
Файл main.qml :
import ...
Window {
...
FocusScope {
...
Column {
...
MyRectangle {
id: rectC
name: "C"
enabled: myProperty
}
...
}
}
...
}
Файл MyRectangle.qml :
import ...
Rectangle {
...
Keys.onReturnPressed: {
myProperty = !myProperty
}
}
К сожалению, нельзя реализовать onEnabledChanged
обработчик событий для MyRectangle
, который позволял бы передавать активный фокус следующему элементу в цепочке фокусировки, когда текущий элемент имеет активный фокус и отключается, потому что когда мы отключаем элемент с активным фокусом, этот обработчик событий вызывается, когда активный фокус уже потерян. Поэтому нельзя знать, какой элемент является следующим для текущего элемента.
Спасибо за любые подсказки!