QT 5.8.0-1: QML ListView: how add Keys.onPressed handler for delegate outside <form>.ui.qml?



  • Hello!

    I have QtQuick UI File with ListView:

     // MyForm.ui.qml
                import QtQuick 2.7
                import conterra 1.0
    
                FocusScope {
                    property alias listView: listView
                    signal select(int currentIndex)
                    ListView {
                        id: listView
                        focus: true
                        clip: true
                        activeFocusOnTab: true
                        anchors.rightMargin: 20
                        anchors.leftMargin: 20
                        anchors.bottomMargin: 20
                        anchors.topMargin: 20
                        anchors.fill: parent
    
                        model: ListModel {
                            ListElement {
                                name: "Автотранспорт"
                                workfront_code: "auto"
                                workfront_id:547292330
                            }
    
                            ListElement {
                                name: "Внутри терминала"
                                workfront_code: "internal"
                                workfront_id:547292331
                            }
                        }
                        delegate: Item {
                            id: delegateItem
                            x: 5
                            width: parent.width
                            height: 40
                            Row {
                                spacing: 10
                                RText {
                                    text: model.name
                                    width: 200*AppTheme.scale
                                }
                                anchors.verticalCenter: parent.verticalCenter
                            }
                            // Keys.onPressed: console.log("test") - this is prohibited by qml ui designer
                            MouseArea {
                                anchors.fill: parent
                                Connections {
                                    onClicked: {
                                        listView.currentIndex = index
                                        select(listView.currentIndex)
                                    }
                                }
                            }
                        }
                        highlight: Rectangle {
                            color: "lightsteelblue"
                        }
                    }
                }
    

    Using designer I cannot use JS for Key.onPressed handler. What is the right way to add Keys.onPressed handler to my List View delegate from controller qml

    // My.qml
    MyForm {
        // how to catch Key.onPressed of my list view delegate?
    }
    

    Thanks in advance!



  • Hello AnatolyS !

    Since you have created 'signal select(int currentIndex)' , you should be albe to catch it with the 'onSelect' handler no ?

    // My.qml
    MyForm {
    // how to catch Key.onPressed of my list view delegate?

    onSelect : {
    //code
    }

    }

    ***sorry if my answer is stupid! may be I did not understand your question.



  • @LeLev Thank you for the response!

    The problem is that I cannot write the following due to UI designer limitation:

    Keys.onPressed: select(listView.currentIndex) - this is prohibited by qml ui designer


  • Hi,

    there are two possible solutions.

    1. Use Connections (http://doc.qt.io/qt-4.8/qml-connections.html)
      The designer does allow JS code if it is in Connections element:
    Connections {
       target: delegateItem.Keys
       onPressed: console.log("test")
     }
    
    1. Move the delegate or even the complete ListView into a separate .qml file.
      Yoe can use refactoring: Move component into separate file for this.
      ListViews and delegates have the tendency to become complex and use declarative QML code,
      so I consider it usually good practice to move them into their own .qml file in any case.
      The <form>.ui.qml file then contains the general layout.


  • @Thomas-Hartmann thank you so much!



  • @Thomas-Hartmann

    when I try to connect to Keys

     delegate: Item {
                    id: delegateItem
                    width: parent.width
                    height:  delegateText.height + 10
                    RText {
                        x: 5
                        id: delegateText
                        text: model.stowage_strip_name
                        anchors.verticalCenter: parent.verticalCenter
                    }
                    Connections {
                       target: delegateItem.Keys
                       onPressed: console.log("test")
                     }
                    MouseArea {
                        anchors.fill: parent
                        Connections {
                            onClicked: {
                                listView.currentIndex = index
                            }
                        }
                    }
                }
    

    I get the following:

     qrc:/pages/SelectExtractModeForm.ui.qml:64:21: QML Connections: Cannot assign to non-existent property "onPressed"
    

    What is wrong?

    Thank in advance!



  • Bump. The solution proposed by Thomas Hartmann using Connections doesn't work even in simpler case, with just a Recatngle in the .ui.qml file and a Connections that targets the rectangle onPressed:

        // In the ui.qml file
        Rectangle {
            id: rectangle
        }
    
        // In the controller qml file
        Connections {
            target: rectangle.Keys
            onPressed: console.log("onPressed")
        }
    

    The error is:
    qrc:/Page1.qml:8:5: QML Connections: Cannot assign to non-existent property "onPressed"
    qrc:/Page1.qml:9:17: Unable to assign undefined to QObject*

    Is this problem solvable without refactoring the Rectangle in a separate qml file?



  • Using forwarddTo property of Keys I'm able to achieve the result:

    In the controller qml file

    import QtQuick 2.7
    
    Page1Form {
    
        id: page1Form
        Keys.onPressed: {
            console.log("KeyPressed")
            event.accepted = true
        }
    
        mouseArea.onEntered: {
            rectangle.forceActiveFocus()
        }
    
        mouseArea.onExited: {
            nextItemInFocusChain(true).focus = true
        }
    }
    

    In the the ui.qml file:

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.3
    
    Item {
        property alias rectangle: rectangle
        property alias mouseArea: mouseArea
        property alias textField: textField
    
        Rectangle {
            id: rectangle
            x: 148
            y: 97
            width: 200
            height: 200
            color: "#ababab"
            Keys.forwardTo: [page1Form]
    
            MouseArea {
                id: mouseArea
                anchors.fill: parent
                hoverEnabled: true
            }
        }
    
        TextField {
            id: textField
            x: 407
            y: 58
            text: qsTr("Text Field")
        }
    }
    

    Just ensure the parent Page1Form won't get the focus for any reason.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.