How to associate view's items with model's ones
-
Hi
I've subclassed QAbstractItemView. I would like to hold some graphical information about view's items.
As each view's item is a representation of model's item I need somehow to link graphical info with model items.It's easy when model desn't change: I can have a map with QModelIndex as a key and my graphical data as value.
Things get complicated when model changes and QModelIndexes become invalid and my data is lost.Is there easy solution for such situations?
I've asked this question on "stack overflow also":http://stackoverflow.com/questions/27587922/storing-persistent-information-about-items-in-view
-
The key idea of MVC pattern is to clearly separate the data (model) from the graphical representation (view),and to make sure those layers do not know too much about one another. So Qt classes will not help you much in achieving your goal, because it does not agree with MVC design.
-
Ok, lets see an example:
I've a tree view:
@
item1
+-----child1
+-----child2
item2
item3
+-----child1
+-----child2
@That's my view. It's hierarchical and two of three top items are expanded.
Now The view gets signal from model, that second top item is to be removed. So we end up with:
@
item1
+-----child1
+-----child2
item3
+-----child1
+-----child2
@Where and how should I store information what my item3 and item1 are expanded and should remain expanded after item2 removal?
I cannot use QModelIndex as reference to model's items as they will change. So when the model changes, currently the only thing I can do is to drop all my data and reread the model again.I don't want to store view's data in model nor modify it. I'd like to have a simple way to keep view's data in view in the way I can find out which model's item they describe.
-
Isn't "QModelIndex::sibling()":http://doc.qt.io/qt-5/qmodelindex.html#sibling what you are after, then?
Not sure why you want to clear the view after model change, though... QTreeView manages model updates automatically. All that is really needed for this to work is a proper implementation of QAbstractItemModel::data() function.
-
Ok, so maybe I'll show my problems a little bit different.
Have you seen how does the QTreeView works?Before I asked my question I had a look this class to find some clues (How to).
And what I saw, was:
they have a vector of tree items (QTreeViewPrivate::viewItems). Each tree item (aka QTreeViewItem) represents model item, holds graphical information (like expanded/colapsed) and holds QModelIndex. This QModelIndex allows them to make a quick jump from tree item to model item.First big (IMHO) problem here is that they do linear search for TreeItem when they have QModelIndex and they need QTreeViewItem (see QTreeView::visualRect & QTreeViewPrivate::viewIndex).
Another big problem is that on every single change in data model, they drop most of the data (whole QTreeViewPrivate::viewItems vector), they reread the model and then recreate some graphical data from other sources (see QTreeView::rowsAboutToBeRemoved and QTreeView::rowsRemoved). Once again linear complexity (or even worse ;) )
Now imagine how does it work for >million items (my case) ;)
So my orignal question was how to solve these two problems, which could be simply solved if we had a way to make a reliable relation between tree item and model item (and with better complexity than O(n) ;) ).