Я использую gridview для отображения сложной модели данных, созданной с помощью c ++ end. У меня все работает нормально, за исключением того, что gridview не принимает и не отвечает на какие-либо события keyNavigation. Вот мой код

GridView{
    id: gridView
    anchors.fill: parent
    clip: true
    cellWidth: 315
    cellHeight: 300/6+15
    focus: true
    model: system.DataList
    highlightFollowsCurrentItem: true
    keyNavigationEnabled: true//enabled but still doesnt work
    //keyNavigationWraps: true//does this matter

    highlight: Rectangle{
        color: highlightColor
        radius: 5
        width: gridView.cellWidth
        height: gridView.cellHeight
        x: gridView.currentItem.x
        y: gridView.currentItem.y
        Behavior on x { SpringAnimation { spring: 3; damping: 0.2 } }
        Behavior on y { SpringAnimation { spring: 3; damping: 0.2 } }
    }

    delegate: Component{
        Rectangle{
            id: viewParentRect
            width: gridView.cellWidth;
            height: diskListView.cellHeight - 15
            color: "transparent"

            Row{
                anchors.fill: parent
                Rectangle{

                    width: parent.width/6 ; height: parent.height
                    color: "transparent"
                    Image {
                        id: image
                        anchors.centerIn: parent
                        source: model.modelData.IconPath
                        sourceSize.width: parent.width
                        sourceSize.height: parent.height
                    }
                }
                Column{
                    Text {
                        id: displayName
                        text: model.modelData.DisplayName
                        font.family: "Sans Serif"
                        font.pointSize: viewParentRect.width/30
                    }
                    Text {
                        id: usageText
                        text: model.modelData.Usage
                        font.family: "Sans Serif"
                        font.pointSize: viewParentRect.width/30
                    }
                }
            }

            MouseArea{
                anchors.fill: parent
                onClicked: {
                    gridView.currentIndex = index
                }
                onDoubleClicked: {
                    system.enter(model.modelData.Path)
                }
            }
        }

    }

}

Я попытался сохранить точки останова в определенных точках, и в результате событие нажатия клавиши не запускалось. Приведенный выше код хорошо работает с мышью, но, поскольку я разрабатываю для настольного компьютера, мне нужна клавиатура для правильной работы (даже если навигация с помощью мыши не работает, это не проблема).

2
killerthawne 20 Ноя 2017 в 10:14

1 ответ

Лучший ответ

Что ж, QML сам по себе предоставляет keyNavigation для GridView и ListView, если для свойства focus установлено значение true, а также имеет фокус пользователя. Фокус может быть нарушен другими компонентами, если они будут созданы позже, и поэтому навигация по клавишам не будет работать должным образом.

В моем случае я создавал два Component / s с двумя разными GridView в обоих, а затем создавал их с помощью StackView, который крал фокус у обоих GridViews.

Моим первым обходным решением было обнаружение keyPress с помощью StackView, и если они являются клавишами со стрелками и / или клавишами ввода / возврата, затем передать их в GridView. Установите false для свойства GridView keyNavigationEnabled и обработайте эти события вручную. Этот метод работал как чемпион, но коды стали слишком сложными. Итак, я написал второй способ.

Динамически создайте два компонента и оставьте только один внутри StackView. Родительский GridView (и другие элементы, которым требуется монопольный фокус) с помощью FocusScope и обнаруживает фокус родительским компонентом и передает их дочернему элементу. В конце позвольте QML обрабатывать все действия с клавишами. Вот код,

Main.qrc

StackView{
        id: stackWindow
        width: mainWindow.width
        height: mainWindow.height
        focus: true
        Component.onCompleted: {push(Qt.createComponent("qrc:/PrimaryHomePage.qml"))}
        onCurrentItemChanged: {currentItem.forceActiveFocus()}
        Connections{
            target: rSystem
            ignoreUnknownSignals: true
            onSwitchBetweenViews: {
                if(newValue === 1){
                    stackWindow.pop()
                    stackWindow.push(Qt.createComponent("qrc:/SecondaryViewPage.qml"))
                }
                else if(newValue === 0){
                    stackWindow.pop()
                    stackWindow.push(Qt.createComponent("qrc:/PrimaryHomePage.qml"))
                }
            }
        }
    }

Сначала выталкивание гарантирует, что StackView владеет только одним элементом в элементе (также можно использовать замену).

PrimaryHomePage.qrc

Item {
id: primaryHomePageParentItem
width: parent.width
height: parent.height

FocusScope{
    id: focusScope
    anchors.fill: parent
    rGridView{
            id: GridView_local
            availablewidth: parent.width
        }
}
onFocusChanged: {focusScope.focus = true}
}

И хорошо, работает даже быстрее, чем первый способ.

1
killerthawne 7 Янв 2018 в 08:09