ListView - Why Space key is never received in Keys.onPressed() signal?
-
In a ListView I'm creating, I need to intercept the Space key, to allow to perform a special action onto the focused item instead of the default view behavior. For that reason I tried to listen the Keys.onPressed signal from inside my ListView component, and to intercept the Space key. However I noticed that this key is never sent to the Keys.onPressed signal, although the other keys are working as expected.
I also tried the Keys.onSpacePressed signal, but it's the same issue: the signal is just never called.
Why this happens, and how can I intercept the Space key in a ListView component?
-
@jeanmilost hi
Make sure focus property is set to true on the ListView
and there is nothing that takes the focus in your listview delegateWindow { visible: true width: 640 height: 480 title: qsTr("Hello World") ListView{ id: view anchors.fill: parent model : ListModel{ ListElement{ name : "el1" } ListElement{ name : "el2" } ListElement{ name : "el3" } } spacing: 2 focus: true delegate: Button{ focus: false focusPolicy: Qt.NoFocus onFocusChanged: if(focus)focus=false width: parent.width height: 50 text : index === view.currentIndex ? "currentIndex" : modelData onClicked: { view.currentIndex = index } } Keys.onPressed: { if (event.key === Qt.Key_Space) { console.log("space clicked"); console.log(view.model.get(view.currentIndex).name) // view.model.get(ind).name = "new value" event.accepted = true; } } } }
-
@LeLev Thank you very much for your answer. It helped me to understand my issue a little more. So I tried your code, and it works, meaning that the
ListView
isn't eating the Space key.However my interface is a little more complex than this one, it contains other objects like
SwipeView
, and yes, my items contain components like buttons which may take the focus. However I already tried to deactivate them and even thus the issue remained.I played a while around the code you posted. I noticed that the following code no longer receives any key:
Rectangle { anchors.fill: parent color: "transparent" visible: true SwipeView { anchors.fill: parent activeFocusOnTab: false Page { background: null ListView { id: view anchors.fill: parent spacing: 2 focus: true model: ListModel { ListElement { name: "el1" } ListElement { name: "el2" } ListElement { name: "el3" } } delegate: Button { focus: false focusPolicy: Qt.NoFocus onFocusChanged: {if (focus) focus = false;} width: parent.width height: 50 text: index === view.currentIndex ? "currentIndex" : modelData onClicked: { view.currentIndex = index } } Keys.onPressed: { console.warn("key clicked"); if (event.key === Qt.Key_Space) { console.log("space clicked"); console.log(view.model.get(view.currentIndex).name); // view.model.get(ind).name = "new value" event.accepted = true; } } } } } }
So I assume that some components operate like filters and may stop internally the keyboard signals, or at least a part of them, without let the choice to the developer to bypass this behavior (or at least I don't know how to do). To be honest I'm a little puzzled, because I worked for15 years with the Windows API before changing for Qt, and receiving a keyboard notification was never an issue, even when the parent component already received it before (in fact it was the contrary: the message could be blocked in the parent, but by default it was passing).
So now the question is: in the above code, how can I receive the keyboard signals, and in particular the Space key, in my
ListView
despite of the parentSwipeView
? Or which solution is normally used in a such situation, e.g is there a way to globally listen the keyboard and intercept keys in the Windows level, BEFORE any component receives them?