In what situations must be the QPersistentModelIndex updated manually?
-
Hi,
according to documentation for sub-classing QAbstractItemModel the beginXXX() and endXXX() family of functions must be used when manipulating with the structure of the model. It does not mention the need for updating the persistent indexes of the model manually. This however is mentioned explicitly for the situations when the layoutAboutToBeCanged() and layoutChanged() are emitted.However I have found that my persistent indexes are not updated by beginXXX and endXXX functions family automatically and they do NOT emit layoutAboutToBeChanged () or layoutChanged() either.
I conclude that I must handle the persistent indexes myself in insert/remove/moveXXX family of virtual functions when re-implementing them.
E.g.
@
beginInsertRows(parent, start, end);//perform insertion procedure
...//update persistent indexes
foreach(const QPersistentModelIndex &perIndex, persistentIndexList())
{
if(perIndex.row() >= row)
changePersistentIndex(perIndex, index(perIndex.row() + (end-start+1), perIndex.column()));
}endInsertRows();
@Since it is not supported by the documentation I am asking whether this assumption is correct or whether I am doing something wrong.
Thank you!
-
Hi, just ran into your post.
I don't have a certain answer to the original question, but I share the same suspicion: QPersistentModelIndex are not updated, specifically on deletion of rows.
We use an extended "Simple DOM Model example":http://qt-project.org/doc/qt-5/qtwidgets-itemviews-simpledommodel-example.html
and made it editable, similar to what was asked in "this post: Simple DOM Model - making it editable ":http://qt-project.org/forums/viewthread/14957
I was never overly confident that my code for adding/removing rows was correct, hence I never posted it as a working solution. But it worked without problems in Qt 4.8, and we heavily rely on QPersistentModelIndex.
We basically used something like this:
@ beginRemoveRows(parent, row, row + count - 1);
int i = 0;
bool success = true;
while (success && i < count) {
//! now the actual model data row
success = parentItem->removeChild(row);
i++;
}
endRemoveRows();@Now we moved to Qt 5.3 and it seems the QPersistentModelIndex list is corrupted after such deletions.
So I also have the suspicion that beginRemoveRows / endRemoveRows() doesn't take care of the QPersistentModelIndex updates any more. But so far I could not find more details about the problem, and I am not aware of any relevant QAbstractItemModel changes between Qt 4.8 and Qt 5.3
Oliver
-
I never used persistent model indices but I would assume that they are invalid after the removal of items and not yet valid after (re-)integration of items.
The Docu says: ...the model will ensure that references to items will continue to be valid as long as they can be accessed by the model. It is good practice to check that persistent model indexes are valid before using them.
-
For clarification, msue - the problem is not with QPersistentModelIndex'es that belonged to any of the rows removed.
The problem is with the remaining parts of the data model (and QPersistentModelIndex that refer to it). In our Qt5 build we have the problem that they now became invalid, too. And, yes, we check for validity before access, but it doesn't help our code that QPersistentModelIndex now became invalid, even if the related DOM node still exists.
But to be fair, there is also a threading / access issue we need to resolve to make sure we are not modifying the model at a time a second thread is reading it using a QPersistentModelIndex. So we are still trying to find the actual cause.
-
Do you update correctly the QPersistentModelIndex objects in all functions that modify the model's structure?
I still wonder why this is not taken care of automatically because the model knows (through beginXXX) what QPersistentModelIndex objects are affected and how they should be changed...
Also regarding the invalidation of some of the persistent indexes. Those whose data is removed are naturally invalidated. However those that are affected by the change to the structure will, after the change, point to the wrong place (or even out of bound place). That is unless you take care of them being updated yourself (see OP).
However, this should not be an issue at all. Upon examining the source code, the QAbstractItemModelPrivate family of functions that are handling the structure changes internally indeed take care of the persistent indexes.
I have not tested it in a while so perhaps I had a different error in my QAbstractItemModel subclass that was causing this behaviour.