简体   繁体   English

QML:Gridview键盘导航不起作用

[英]QML: Gridview keyboard navigation not working

I'm using a gridview to display a complex data model generated from c++ end. 我正在使用gridview显示从c ++端生成的复杂数据模型。 I've everything working fine except that the gridview doesn't accept or respond to any keyNavigation events. 除了gridview不接受或响应任何keyNavigation事件之外,我一切正常。 Here's my code 这是我的代码

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

    }

}

I tried keeping breakpoints at certain points and the result was, no keypress event is fired at all. 我尝试将断点保持在某些点,结果是,根本没有触发按键事件。 Above code is working well with mouse but since I'm developing for desktop, I need keyboard navigation to work properly ( even if mouse navigation doesn't work, its not a problem). 上面的代码可以很好地与鼠标配合使用,但是由于我是为台式机开发的,因此我需要键盘导航才能正常工作(即使鼠标导航不起作用,这也不成问题)。

Well, QML provides keyNavigation by itself for GridView and ListView, so long as it has focus property set to true and also has user focus. 好吧,QML本身为GridView和ListView提供keyNavigation,只要它具有focus属性设置为true且还具有用户焦点即可。 Focus can be stollen by other components, if they are created afterwards and thats why key navigation would not work as expected. 如果其他组件是事后创建的,则焦点可能会被其他组件所窃取,这就是为什么键导航无法按预期工作的原因。

In my case, I was creating two Component/s with two different GridViews in both and then parenting it with StackView which was stealing the focus from both the GridViews. 就我而言,我正在创建两个具有两个不同GridView的Component,然后将其与StackView作为父级,这从两个GridView窃取了焦点。

My first workaround was to detect keyPresses by StackView and if they are arrow keys and/or enter/return keys then pass them to GridView. 我的第一个解决方法是通过StackView检测keyPresses,如果它们是箭头键和/或Enter / return键,则将它们传递给GridView。 Set false to GridView keyNavigationEnabled property and handle these events manually. 将GridView的keyNavigationEnabled属性设置为false并手动处理这些事件。 This method worked like a champ but codes became too complex. 这种方法像冠军一样工作,但是代码变得太复杂了。 So I wrote the second method. 所以我写了第二种方法。

Dynamically create the two components and keep only one inside the StackView. 动态创建两个组件,并在StackView中仅保留一个组件。 Parent GridView (and other items which need exclusive focus) with a FocusScope and detect the focus by parent Component and transfer them to child. 具有FocusScope的父GridView(以及其他需要排他焦点的项目),并通过父Component检测焦点,并将其转移给子组件。 At the end, let the QML handle all key navigations. 最后,让QML处理所有关键导航。 Here's the code, 这是代码,

main.qrc 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"))
                }
            }
        }
    }

Popping first ensures that StackView owns only one item at a item (replace can be used as well). 首先弹出,以确保StackView在一个项目中仅拥有一个项目(也可以使用替换)。

PrimaryHomePage.qrc 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}
}

And good thing, it works even faster than the first method. 幸运的是,它的工作速度比第一种方法还要快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM