[英]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.