QML определяет последовательность цепочки фокусировки с помощью JavaScript

#javascript #qt #qml

#javascript #qт #qml #qt

Вопрос:

Я хочу определить пользовательскую цепочку фокусировки в QML таким образом, чтобы существовала функция JavaScript, которая решает, какой элемент получит фокус следующим. Цепочка фокусировки определяется массивом. Код следующий:

 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();
        }
    }
}
  

Я получаю много подобных сообщений:

 QML KeyNavigation: Binding loop detected for property "tab"
  

и из выходных данных видно, что эта функция выполняется более одного раза для каждого элемента. Что я делаю не так?

Ответ №1:

это вызвано привязкой. Каждый раз, когда выполняется «testFocusDispatcher», «currentId» будет меняться, что приведет к переоценке привязки, что приведет к выполнению «testFocusDispatcher» и т.д… вы видите проблему!

Я бы вместо этого сделал что-то вроде этого:

 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
        }
    }
}