I've my own view based directly on QAbstractItemView
.
Generally speaking I need to store some information about particular model's item.
So in my view I have a map from QModelIndex
to struct describing partical item.
Then I use those data mostly on view's paintEvent
.
The problem is, that QModelIndex is not persistent, it may get outdated.
So when rows are inserted or removed from model, some QModelIndex
may become invalid and I should not relay on them.
How then can I build relation between item in model and some decoration data I use in view?
QPersistentModelIndex
seems to be proper tool for such things, however I'm aware of its performance (my model and view may be huge).
Another problem with QPersistentModelIndex
is that it probably should not be used as map's key (as it is in my case) as it may (and will) change and make map inconsistent.
I've took a look at Qt's implementation of QTreeView and QListView to see how they deal rows removal/insertion, but it seems they simply drop all the data.
So at this point I cannot see any easy way to solve my problem.
You can safely use a QPersistentModelIndex
as a map or hash key.
Even if the underlying QModelIndex changes, the "persistent" part ensure that all the QPersistentModelIndex
are kept up to date while preserving their identities, i.e operator ==
and qHash()
return consistent values.
That being said, you should not store data about the index in your view. The data are supposed to be stored by the model.
And this seems to be how its done in Qt classes: views are making a lot of calls to QAbstractItemModel::data()
.
The only data that I would deem worthy to be stored in the view is "cache data", i.e values that are:
If any of these 3 conditions is not met, my personal preference would be to store the data in the model.
Contrary to my original answer, you cannot safely use QPersistentModelIndex
as a QMap
key.
The reason is that QMap
uses operator <
for inserting and finding data.
The issue here is that bool QPersistentModelIndex::operator<(const QPersistentModelIndex &other) const
is just a proxy to bool QModelIndex::operator<(const QModelIndex &other) const
which compares indexes by row and column.
This means that the sort order of QPersistentModelIndex
is not persistent and will change when indexes are moved in the model.
However, QMap
is not aware that the sort order has changed. And at this point searching a value inside a QMap<QPersistentModelIndex, T>
is just as broken as doing binary search on an unsorted array.
Note that this issue is not limited to QMap
, it affects all containers which are based on the ordering of the keys like std::map
. However, containers that do not rely on ordering (QHash
, std::unordered_map
, ...) are not affected.