2010-04-15 349 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()信號。