Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 delegate

    Window {
        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 parent SwipeView? 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?