2010-04-15 355 views
1

我正在编写一个简单的测试程序,使用QTreeModel和QTreeView来处理更复杂的项目。在这个简单的程序中,我有可能会收缩或扩大的组中的数据,正如人们在QTreeView中预期的那样。数据也可以按各种数据列排序(QTreeView.setSortingEnabled为True)。每个树项目是数据列表,所以TreeModel中的类实现排序功能使用内置的Python列表排序:PyQt:如何使QTreeView节点在排序后正确展开

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() 

的问题是,每当我改变了根的子项的分类(中树只有2层深,所以这是唯一有孩子的层次),节点不一定像以前那样扩大。如果我在不扩展或折叠任何东西的情况下将排序改回来,那么节点会在排序更改之前展开。
任何人都可以向我解释我做错了什么?我怀疑这是没有正确重新分配QModelIndex与排序的节点,但我不知道。

回答

1

我通过为排序实现QSortFilterProxyModel来解决问题。

+0

很高兴在原始问题中看到SSCCE,并在答案中实现了解决方案。不算太晚! – neuronet 2016-04-18 13:11:16

2

要回答你的问题“我做错了什么” - 你在发布layoutChanged()之前没有更新持久模型索引。你的模型的客户不会奇迹般地知道你的模型的数据是如何移动的;例如,他们不知道索引(2,0,root)移到了(12,0,root)。

沟通变化的方式是通过发布布局信号;你有这个部分是正确的。 Qt最有可能通过转换它保存到QPersistentModelIndex中的任何QModelIndexes来响应layoutAboutToBeChanged()。当它得到layoutChanged()它将它们转换回来。在中间,您应该查看QPersistentModelIndex列表并使用新位置更新索引。检查文档layoutChanged()信号。