9

While skimming the QML Documentation, I found this commendable documented class: ItemSelectionModel

There is the C++-Class QItemSelectionModel which provides some more detail on it's purpose to keep track on the selection of Items within a model.

However on the QML-Side I have not the slightes clue, on how to use it.

Lets say, I have this ListModel

ListModel {
    id: lm
    ListElement { value: 0 }
    ListElement { value: 0 }
    ListElement { value: 0 }
    ListElement { value: 0 }
    ListElement { value: 1 }
    ListElement { value: 1 }
    ListElement { value: 2 }
    ListElement { value: 2 }
    ListElement { value: 0 }
    ListElement { value: 0 }
    ListElement { value: 2 }
    ListElement { value: 2 }
}

Now I have a View in which I display all of this model, and a second view in which I only want to display a selection of it. So I created a ItemSelectionModel and called the select-method of it from the delegates of the first view which seemed to have no effect at all. Not even the hasSelection-property bothered to change.

Repeater {
    model: lm
    delegate: Rectangle {
        property int row: Math.floor(index / 4)
        property int column: index % 4
        width: 100
        height: 100
        x: 100 * column
        y: 100 * row
        border.color: 'black'

        MouseArea {
            anchors.fill: parent
            onClicked: {
                ism.select(index, ItemSelectionModel.Select | ItemSelectionModel.Current)
                console.log(ism.hasSelection)
            }
        }
    }
}

ItemSelectionModel {
    id: ism
    model: lm
}

So I wonder what is the purpose of this Component, that seems to do nothing at all. Or, how can I get it to do something purposeful?

1 Answers1

9

The documentation is indeed not at all helpful. Sorry for that, I've filed a bug to look into fixing it.

In the QML world, it is supposed to fulfill the same function as QItemSelectionModel (i.e. keeping the selection state of multiple views in sync) -- indeed, the implementation in QML is directly instantiating and calling is actually the same as QItemSelectionModel's.

This may actually be the source of your trouble, as QML's views do not use QModelIndex (which QItemSelectionModel requires), but rather, an int index referring to the row number of the model. To get a QModelIndex, you can call QAbstractItemModel::index, like so:

onClicked: {
    // note: lm here is the id of your ListModel
    ism.select(lm.index(index, 0), ItemSelectionModel.Select | ItemSelectionModel.Current)
    console.log(ism.selectedIndexes)
    console.log(ism.hasSelection)
}
Robin Burchell
  • 871
  • 5
  • 9
  • Thanks for pointing out `index()` and (by proxy) the other undocumented `Q_INVOKABLE`s of `QAbstractItemModel`! – Maxim Paperno Jul 27 '18 at 20:12
  • Using onClicked handler does not work with a TreeView (QCC2), since it disables ability to navigate tree with mouse (even if propogating mouse event and accepted set to false). But hooking into the onchanged event for current item works. – TSG Apr 23 '21 at 20:47