QML:Gridview键盘导航无法正常工作

时间:2017-11-20 07:14:55

标签: qt qml keyboard-events

我正在使用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)
                }
            }
        }

    }

}

我尝试在某些点保留断点,结果是,根本没有触发按键事件。上面的代码适用于鼠标,但由于我正在为桌面开发,我需要键盘导航才能正常工作(即使鼠标导航不起作用,也不是问题)。

1 个答案:

答案 0 :(得分:0)

好吧,QML为GridView和ListView提供了自己的keyNavigation,只要它将focus属性设置为true并且还具有用户焦点。如果它们是在之后创建的,那么焦点可能会受到其他组件的影响,这就是为什么键导航无法按预期工作。

就我而言,我创建了两个Component / s,两个GridView都有两个不同的GridView,然后使用StackView对其进行渲染,这会从两个GridView中窃取焦点。

我的第一个解决方法是通过StackView检测keyPresses,如果它们是箭头键和/或输入/返回键,则将它们传递给GridView。将false设置为GridView keyNavigationEnabled属性并手动处理这些事件。这种方法就像一个冠军,但代码变得过于复杂。所以我写了第二种方法。

动态创建两个组件,并在StackView中只保留一个组件。使用FocusScope的父GridView(以及需要独占焦点的其他项)并通过父Component检测焦点并将它们传输给child。最后,让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}
}

好的,它比第一种方法更快。