简短版
我正在尝试显示QAbstracctTableModel
中QTreeView
的数据。当我这样做时,我最终将整个表显示为每个节点(和孙子等等)的子节点。如何显示抽象表模型的树视图?
详情
我正在尝试在QAbstractTableModel
的{{1}}中显示一些数据。在Model-View Tutorial中,在提供示例QTreeView
之后,它似乎就像用QAbstractTableModel
替换QTableView
一样简单:
您可以将上面的示例转换为具有树的应用程序 视图。 只需将QTableView替换为QTreeView ,即可生成一个 读/写树。不需要对模型进行任何更改。
当我进行此替换时,我最终会显示一个树,但是如果我点击任何图标来展开它(由于没有内置层次结构,它应该什么也不做),Python崩溃了{{ 1}}。这个has been brought up before],但没有可行的解决方案。
为了尝试修复此行为,我在QTreeView
子类中重新实现了索引函数(请参阅下面的完整工作示例)。这导致了非常不同类型的错误。也就是说,树中的每个节点现在都包含整个表作为数据。无论我点击多少次,整个表格都会显示出来。像这样:
我似乎处于某种递归的噩梦中,并且不知道如何逃避。下面的相关问题表明我可能必须转到Python.exe has stopped working
,但上面的教程引用另有说明(其中,不需要对模型进行任何更改)。
相关问题
QTreeView always displaying the same data
完整的工作示例
QAbstractTableModel
答案 0 :(得分:4)
实现基于表的模型时,
rowCount()
应在父项有效时返回0。
columnCount()
也是如此。为完整起见,如果父级有效,data()
应返回None
。
这是怎么回事:
rowCount()
,并通过了作为父母的“Stinkberries”单元格的索引。FavoritesTableModel::rowCount()
返回5,所以QTreeView认为,“啊,'Stinkberries'下有5行。” data()
,传递第0行,第0列,以及“Stinkberries”单元格的索引作为父级。FavoritesTableModel::data()
返回“苹果”,所以QTreeView认为,“啊,'Stinkberries'下的第一个项目是'苹果'。” 要获得正确的行为,您的代码必须为步骤#3和#4返回0。
最后,为了确保“+”符号根本不显示,make hasChildren()
会为每个单元格返回false。
答案 1 :(得分:3)
<强>解决方案强>
理论上,Model-View框架的一个很好的特性是您可以拥有同一模型的多个视图。但实际上,QAbstractTableModel
实际上是为了帮助您查看表格,而不是树木。 QAbstractTableModel
的{{3}}说:
由于该模型提供了比它更专业的界面 QAbstractItemModel,它不适合与树视图一起使用
然而,即使有这个警告,也有办法让这个工作。首先,正如JKSH所指出的,你必须修复rowCount
(并注意它的第二个参数是父索引):
def rowCount(self, parent=QtCore.QModelIndex()):
if parent.isValid():
return 0
return len(self.foods)
其次,删除index
的不切实际的重新实现,这使得选择行为真的很奇怪,原因我坦率地不理解。
但是,一般情况下,如果你想要一个通用模型,那么从QAbstractItemModel
而不是一个预先制作的模型中播放它是安全的和子类。
<强>讨论强>
在表格模型中,忽略rowCount
内的父级是可以接受的。在官方Qt书中,它们遵循标准程序,即rowCount
仅返回要在表格中显示的行数。 Blanchette和Summerfield注:
父参数对表模型没有意义;它就在那里 因为rowCount()和columnCount()是从更多继承的 通用QAbstractItemModel基类,支持heirarchies。 (p 255)
在他的PyQt书中,Summerfield指出:
[T]他的父母QModelIndex p仅对树模型有用(第434页)
基本上,rowCount
会告诉您父项下面要显示的行数。因为在表中所有项都具有相同的父项,所以在QTableView
s中不使用父项。但是由于JKSH在答案中非常清楚地指出了这个策略,这个策略不再适用于树木。
因此,声称父参数&#34;对表模型没有意义&#34;应该修改仅当数据将由QTableView
显示时才会出现这种情况(这通常是一个很好的假设)。