I'm writing a simple test program using QTreeModel and QTreeView for a more complex project later on. In this simple program, I have data in groups which may be contracted or expanded, as one would expect in a QTreeView. The data may also be sorted by the various data columns (QTreeView.setSortingEnabled is True). Each tree item is a list of data, so the sort function implemented in the TreeModel class uses the built-in python list sort:
self.layoutAboutToBeChanged.emit()
self.rootItem.childItems.sort(key=lambda x: x.itemData[col], reverse=order)
for item in self.rootItem.childItems:
item.childItems.sort(key=lambda x: x.itemData[col], reverse=order)
self.layoutChanged.emit()
The problem is that whenever I change the sorting of the root's child items (the tree is only 2 levels deep, so this is the only level with children) the nodes aren't necessarily expanded as they were before. If I change the sorting back without expanding or collapsing anything, the nodes are expanded as before the sorting change.
Can anyone explain to me what I'm doing wrong? I suspect it's something with no开发者_Python百科t properly reassigning QModelIndex with the sorted nodes, but I'm not sure.To answer your question "what I'm doing wrong" -- you didn't update the persistent model indexes before emitting layoutChanged(). The clients of your model don't magically know how your model's data has moved; for example, they don't know that the index (2,0,root) moved to become (12,0,root).
The way you communicate the change is by emitting the layout signals; you have that part correct. Qt most likely responds to layoutAboutToBeChanged() by converting any QModelIndexes it keeps into QPersistentModelIndex. When it gets layoutChanged() it converts them back. In-between, you're supposed to look through that QPersistentModelIndex list and update the indexes with new locations. Check the docs for the layoutChanged() signal.
I solved the problem by implementing a QSortFilterProxyModel for the sort.
精彩评论