Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Forwarding keys to a Listview delegate inside a Popup
QtWS25 Last Chance

Forwarding keys to a Listview delegate inside a Popup

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qmlautocompletekeys.forwardto
3 Posts 2 Posters 3.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Curtwagner1984
    wrote on 6 May 2017, 19:20 last edited by
    #1

    I'm trying to implement an autocomplete box similar to this https://material.angularjs.org/latest/demo/autocomplete.
    I'm using a TextField and a Popup with a listview to show the suggestions, but I'm having trouble forwarding keys from TextField to the listview delegate.

    What I'm doing now is opening the popup on the textfield onTextChanged event and then query the database for suggestions and populate the suggestions model. I'm using Keys.forwardTo to forward key events from the textfield to the listview in the popup, and it works fine, for navigation. But I can't figure out select an element from the list using 'return' key.

    This is main.qml

    TextField {
        id: searchBar
        placeholderText: "Search..."            
        focus: true
        property string searched_text: searchBar.text
        onTextChanged: {
          qmlComm.autoCompleteSearch(searchBar.text)
          autocomplete.open()
        }
        Keys.forwardTo: [autocomplete.autocompleteListViewAlias]            
    }
    
    AutoCompletePopup{
            id: autocomplete
            x:searchBar.x
            y:searchBar.y - 10
            height: mainAppPage.height / 2
            width: searchBar.width
        }
    

    This is popup.qml:

    Popup {
        id: autoCompletePopup
        property alias autocompleteListViewAlias: autoCompleteListView
        x: 200
        y: 200
        width: 200
        height: 400
        modal: false
        focus: false
        clip: true
        closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
    
        Component {
            id: highlightBar
            Rectangle {
                width: autoCompleteListView.width
                height: 60
                color: Material.color(Material.Pink)
                opacity: 0.7
                y: autoCompleteListView.currentItem.y            
            }
        }
    
        Rectangle {
            id: autoCompleteRect        
            color: "transparent"
            height: autoCompletePopup.height
            width: autoCompletePopup.width
    
            ListView {
                id: autoCompleteListView
                anchors.fill: parent
                model: autoCompleteModel            
                delegate: Item {
                    id: autoCompleteDelegate
                    height: 60
                    Rectangle {
                        id: autoCompleteDelegateBackground
                        width: autoCompleteListView.width
                        height: 60
                        focus: true
                        color: "transparent"
                      
                        Text {
                            id: autoCompleteItemName
                            text: name
                            font.capitalization: Font.Capitalize
                            anchors.left: autoCompleteDelegateBackground.left
                            anchors.leftMargin: 10
                            anchors.verticalCenter: autoCompleteDelegateBackground.verticalCenter
                        }
                        
    
                        MouseArea {
                            id: autoCompleteMouseArea
                            anchors.fill: autoCompleteDelegateBackground
                            onClicked: {
                                console.log("You clicked " + tableName + " " + name + " " + id)  //tableName,name and id are model role names
                                autoCompleteListView.currentIndex = index
                            }
                        }
                        // this is the problem, this event does not trigger
                        Keys.onReturnPressed: {               
                            console.log("Pressed Enter on " + name)
                        }
    
                        
    
                    }
                }
                // successfully triggered when keys are forwarded
                Keys.onPressed: {
                   if (event.key === Qt.Key_Down) {
                       console.log("AUTOCOMPLETE : Pressed down")
                   } else if (event.key === Qt.Key_Up) {
                       console.log("AUTOCOMPLETE : Pressed up")                    
                   } else if (event.key === Qt.Key_Return) {
                       console.log("AUTOCOMPLETE : Pressed enter")
                   }
               }
                highlight: highlightBar
                highlightFollowsCurrentItem: false
                ScrollBar.vertical: ScrollBar {
                }
                focus: false
                clip: true
            }
        }
    }
    

    I managed to get the navigation and selection behavior I want if I force the focus on the delegate on a mouse click like so : (in the mousearea on click event) autoCompleteListView.forceActiveFocus(); But then the textbox looses focus and the user can no longer type.
    I'm looking for a way to react to a Keys.onReturnPressed event inside the delegate, or some other solution that would help me select an item from a listview while maintaining the focus on the textedit.

    Thank You!

    P.S, I'm new to QML and Qt, so I'm also open to any suggestions that would help me build an autocomplete box that use completely different approach from what I have taken.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      jpnurmi
      wrote on 7 May 2017, 10:52 last edited by
      #2

      Does this do more or less what you want (besides that it's using a dummy model instead of doing any actual filtering)?

      import QtQuick 2.6
      import QtQuick.Controls 2.0
      
      ApplicationWindow {
          width: 640
          height: 480
          visible: true
      
          TextField {
              id: textField
              focus: true
              anchors.centerIn: parent
              onTextChanged: popup.open()
              Keys.forwardTo: [listView.currentItem, listView]
      
              Popup {
                  id: popup
                  padding: 1
                  y: parent.height
                  width: parent.width
                  contentHeight: listView.contentHeight
      
                  ListView {
                      id: listView
                      currentIndex: 0
                      anchors.fill: parent
                      model: ["foo", "bar", "baz"]
                      delegate: ItemDelegate {
                          text: modelData
                          width: parent.width
                          highlighted: index === listView.currentIndex
                          Keys.onReturnPressed: {
                              textField.text += text
                              popup.close()
                          }
                      }
                  }
              }
          }
      }
      
      1 Reply Last reply
      2
      • C Offline
        C Offline
        Curtwagner1984
        wrote on 7 May 2017, 14:10 last edited by
        #3

        Yes! Adding forwarding to listview.currentItem does exactly what I want. Thank You!

        1 Reply Last reply
        0

        1/3

        6 May 2017, 19:20

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved