Reputation: 1425
I want to define custom focus chain in QML in a way, that there is a JavaScript function, that decides, which element gets the focus next. The focus chain is defined by array. The code is the following:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
Window {
width: 640
height: 480
visible: true
title: qsTr("Focus sandbox")
Grid {
width: 100; height: 100
columns: 2
property variant ids: [topLeft,topRight,bottomLeft,bottomRight]
property variant currentId: 0
function testFocusDispatcher()
{
console.log("Current id: "+currentId)
if(currentId<3)
{
currentId++;
}
else
{
currentId=0;
}
return ids[currentId];
}
Rectangle {
id: topLeft
width: 50; height: 50
color: focus ? "red" : "lightgray"
focus: true
KeyNavigation.tab: parent.testFocusDispatcher();
}
Rectangle {
id: topRight
width: 50; height: 50
color: focus ? "red" : "lightgray"
KeyNavigation.tab: parent.testFocusDispatcher();
}
Rectangle {
id: bottomLeft
width: 50; height: 50
color: focus ? "red" : "lightgray"
KeyNavigation.tab: parent.testFocusDispatcher();
}
Rectangle {
id: bottomRight
width: 50; height: 50
color: focus ? "red" : "lightgray"
KeyNavigation.tab: parent.testFocusDispatcher();
}
}
}
I receive a lot of messages like this:
QML KeyNavigation: Binding loop detected for property "tab"
and see from the output, that this function runs more than once for each element. What am I doing wrong?
Upvotes: 0
Views: 383
Reputation: 2388
this is caused because of the binding. Each time "testFocusDispatcher" is executed "currentId" will change which will cause the binding to reevaluate which causes "testFocusDispatcher" to execute etc... you see the problem!
I would instead do something like this:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
Window {
width: 640
height: 480
visible: true
title: qsTr("Focus sandbox")
Grid {
id: grid
columns: 2
spacing: 2
property variant ids: [topLeft,topRight,bottomLeft,bottomRight]
property variant currentId: 0
Keys.onTabPressed: {
console.log("Current id: " + grid.currentId)
if(grid.currentId < 3) {
grid.currentId++;
}
else {
grid.currentId=0;
}
}
Rectangle {
id: topLeft
width: 50; height: 50
color: focus ? "red" : "lightgray"
focus: grid.ids[grid.currentId] === this
}
Rectangle {
id: topRight
width: 50; height: 50
color: focus ? "red" : "lightgray"
focus: grid.ids[grid.currentId] === this
}
Rectangle {
id: bottomLeft
width: 50; height: 50
color: focus ? "red" : "lightgray"
focus: grid.ids[grid.currentId] === this
}
Rectangle {
id: bottomRight
width: 50; height: 50
color: focus ? "red" : "lightgray"
focus: grid.ids[grid.currentId] === this
}
}
}
Upvotes: 1