Multiple interleaving QAbstractItemModel::beginInsertRows()/beginRemoveRows() followed by a single endInsertRow()/endRemoveRow() call?

Viewed 508

I am developing a top/htop clone in Qt supposed to display the processes on a remote device. A fresh list of processes is transmitted every second and causes the internal QAbstractItemModel derivative representing the states in the client to update. This happens in a loop that uses two iterators (one for the old list and one for the fresh list) that I simultaneously iterate through to compare the entries and apply changes (i.e. remove/insert/update entries) if neccessary.

I would like to know if every beginInsertRows/beginRemoveRows call must be immediately followed by a closing endInsertRows/endRemoveRows call after the respective change or whether it is ok to have boolean flags indicating that indeed an insertion/removal has taken place and then carry on applying more insertions/removals and only at the end call endInsertRows/endRemoveRows once depending on the previously mentioned flags.

Since a potentially large number of entries in the model might have changed (in turn triggering a large number of insertions/removals) I am concerned with the performance and wouldn't like the model to notify the views for an update until I am done with all insertions/removals.

Is that possible or shouldn't I care about that because Qt already has some internal optimizations to automatically handle such cases which I am not aware of?

Edit 1: Empty rows followed by a crash seem to have answered the question as can be seen in this image.

1 Answers

Whenever you insert a row in the middle, you invalidate at least the indices of the following rows.

Calling beginInsertRow() tells the view(s) that its stored / cached indices are going to be invalidated, and in which way. It kind of tells the view that the model is transisting into an intermediate / invalid state.

Calling endInsertRow() tells the view that now the model's internal state is valid and can be queried.

Nesting these calls is not supported.

Maybe you should use begin/endResetModel() instead.

Related