flaskoln
flaskoln

Reputation: 97

Qt QML Notify ListView when items in the model are added or removed

My ListView should always scroll its currently active item to the top between preferredHighlightBegin and preferredHighlightEnd. That works while clicking an item. However when a new item is added to my AbsctractListModel (And its not just added on the end but could be added anywhere in the middle), the ListView shows the new item, but it is not scrolled to the top. This is most likely because list.currentIndex = index is not set for new added items. I want to set it but did not find a way yet to do so. Does anyone have a hint?

I tried different signals such as onCurrentItemChanged but did not find the proper one yet which also gives me the correct index.

ListView {
    id: list
    anchors.fill: parent
    clip: true
    spacing: 11
    focus: true
    highlightMoveDuration: 400
    snapMode: ListView.SnapToItem
    preferredHighlightBegin: 0
    preferredHighlightEnd: 100
    highlightRangeMode: ListView.StrictlyEnforceRange

    model: myAbstractListModel

    delegate: ListItem {
                  height: 56
                  width: list.width
                  color: "red"
                  onListItemClicked: {
                      list.currentIndex = index
                  }
              }
}

The expected result would be a ListView which scrolls a programmatically new added item of my AbstractListModel to the top (between preferredHighlightBegin and preferredHighlightEnd).

Upvotes: 4

Views: 2785

Answers (1)

Silvano Cerza
Silvano Cerza

Reputation: 970

Adding this to your ListView will change the current index to the last one whenever the number of items in the model changes, you might want to keep track of the previous items count if you want to scroll only on insertion.

onCountChanged: {
    if (count > 0) {
        currentIndex = count - 1;
    }
}

If the new items might be inserted anywhere in the model you could connect directly to it using the Connections item inside your ListView and connect it directly to the rowsInserted signal of QAbstractItemModel.

Connections {
    target: model
    onRowsInserted: {
        currentIndex = first + 1;
    }
}

If your model emits only the dataChanged signal you can try this.

Connections {
    target: model
    onDataChanged: {
        currentIndex = topLeft.row() + 1;
    }
}

Upvotes: 5

Related Questions