2
votes

I'm using QtQuick 2.0 and and a QML ListView to display some items, and I need to know when the user chooses a different item. Emitting a signal when the user clicks a mouse area in the delegate works, i.e.

MouseArea{
    onClicked: {
                 controller.itemChanged(model.item);
                 someList.currentIndex = index;
   }
}

but only if the user uses the mouse to choose the item, but it doesn't work if the user uses the arrow keys.

I've been looking through the docs to find what signal is emitted when the currentIndex is changed, but I can't seem to find any. I'm looking for something similar to QListWidget::itemSelectionChanged() but it seems QML ListView doesn't have that.

3
You mean onCurrentIndexChanged signal? All notifiable properties have their on<name>Changed property.Arpegius
Wow.. can't believe I missed that and went around the block instead.chyyran

3 Answers

2
votes

You just need onCurrentItemChanged:{} in your ListView.

0
votes

I ended up having to re-implement keyboard behaviour and exposing the model data from the delegate so I could fire the signal when a key is pressed.

ListView {
    id: myList
    focus: true
    orientation: "Horizontal" //This is a horizontal list
    signal itemChanged(var item)
    interactive: false //Disable interactive so we can re-implement key behaviour
    Keys.onPressed: {
                if (event.key == Qt.Key_Left){
                    myList.decrementCurrentIndex(); //Change the current list selection
                    itemChanged(myList.currentItem.selectedItem.data); //Fire signal notifying that the selectedItem has changed
                }
                else if (event.key == Qt.Key_Right){
                    myList.incrementCurrentIndex(); //Change the current list selection
                    itemChanged(myList.currentItem.selectedItem.data); //Fire signal notifying that the selectedItem has changed
                }
            }

    delegate: Component {
        Rectangle {
            id: myItem
            property variant selectedItem: model //expose the model object

            MouseArea {
                anchors.fill: parent
                onClicked: {
                    myList.currentIndex = index; //Change the current selected item to the clicked item
                    itemChanged(model.data); //Fire signal notifying that the selectedItem has changed
                }
            }
        }
    }
}

With this solution you have to manually change the item in QML whenever the user clicks an item or presses a key. I'm not sure this'd be an optimal solution with GridView but it works fine with ListView.

0
votes

See this question. There are two approaches you can take

  1. Connect to another component's event
  2. Handle the event within that component

The signal handler is named on<SignalName> with the first letter of the signal in uppercase.