Search code examples
qtqmlqkeyevent

QML propagate key events from ListView delegates


main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    onActiveFocusItemChanged: console.log(activeFocusItem)

    Item {
        id: item
        anchors.fill: parent
        focus: true

        ListView {
            anchors.fill: parent
            model: ["Test1", "Test2", "Test3", "Test4", "Test5"]
            delegate: TextArea {
                padding: 0
                text: modelData
            }
        }

        Keys.onReleased: {
            if(event.key === Qt.Key_F3) {
                console.log("F3 pressed")
                event.accepted = true
            }
        }
    }
}

I would like to intercept the click of the key F3 in the item but, when the focus is on the ListView delegates, they don't propagate the key event. If instead the focus is on the Item, everything works fine.
How can I solve that?


Solution

  • The TextArea must try to catch the F3 key itself, which is why it doesn't propogate. The way I would fix this is to catch the key both in the delegate and out of the delegate, and in both handlers call a common function to do the actual work that you want to do.

    Item {
        id: item
        anchors.fill: parent
        focus: true
    
        ListView {
            anchors.fill: parent
            model: ["Test1", "Test2", "Test3", "Test4", "Test5"]
            delegate: TextArea {
                padding: 0
                text: modelData
                Keys.onReleased: {
                    if(event.key === Qt.Key_F3) {
                        // Just call the new function we created
                        item.f3Handler();
                        event.accepted = true
                    }
                }
            }
        }
    
        Keys.onReleased: {
            if(event.key === Qt.Key_F3) {
                // Just call the new function we created
                f3Handler();
                event.accepted = true
            }
        }
    
        // This is where we do the actual work.
        function f3Handler() {
            console.log("F3 pressed")
        }
    }