PyQt:如何在排序后保持 QTreeView 节点正确展开

发布于 2024-08-29 07:01:55 字数 661 浏览 6 评论 0原文

我正在使用 QTreeModel 和 QTreeView 编写一个简单的测试程序,以便稍后进行更复杂的项目。在这个简单的程序中,我将数据分组,这些数据可以收缩或扩展,正如人们在 QTreeView 中所期望的那样。数据还可以按各种数据列排序(QTreeView.setSortingEnabled 为 True)。每个树项都是一个数据列表,因此 TreeModel 类中实现的排序函数使用内置的 python 列表排序:

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 与排序节点的问题,但我不确定。

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 not properly reassigning QModelIndex with the sorted nodes, but I'm not sure.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅气称霸 2024-09-05 07:01:56

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

传达更改的方式是发出布局信号;你那部分是正确的。 Qt 最有可能通过将其保留的任何 QModelIndexes 转换为 QPersistentModelIndex 来响应 layoutAboutToBeChanged()。当它获取layoutChanged()时,它会将它们转换回来。在这之间,您应该查看 QPersistentModelIndex 列表并使用新位置更新索引。检查文档中的layoutChanged() 信号。

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.

给不了的爱 2024-09-05 07:01:56

我通过实现 QSortFilterProxyModel 进行排序解决了这个问题。

I solved the problem by implementing a QSortFilterProxyModel for the sort.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文