在QTreeView中显示QAbstractTableModel的数据

时间:2014-12-05 03:35:29

标签: qt pyqt pyside

简短版

我正在尝试显示QAbstracctTableModelQTreeView的数据。当我这样做时,我最终将整个表显示为每个节点(和孙子等等)的子节点。如何显示抽象表模型的树视图?

详情

我正在尝试在QAbstractTableModel的{​​{1}}中显示一些数据。在Model-View Tutorial中,在提供示例QTreeView之后,它似乎就像用QAbstractTableModel替换QTableView一样简单:

  

您可以将上面的示例转换为具有树的应用程序   视图。 只需将QTableView替换为QTreeView ,即可生成一个   读/写树。不需要对模型进行任何更改。

当我进行此替换时,我最终会显示一个树,但是如果我点击任何图标来展开它(由于没有内置层次结构,它应该什么也不做),Python崩溃了{{ 1}}。这个has been brought up before],但没有可行的解决方案。

为了尝试修复此行为,我在QTreeView子类中重新实现了索引函数(请参阅下面的完整工作示例)。这导致了非常不同类型的错误。也就是说,树中的每个节点现在都包含整个表作为数据。无论我点击多少次,整个表格都会显示出来。像这样:

bad tree

我似乎处于某种递归的噩梦中,并且不知道如何逃避。下面的相关问题表明我可能必须转到Python.exe has stopped working,但上面的教程引用另有说明(其中,不需要对模型进行任何更改)。

相关问题

QTreeView always displaying the same data

完整的工作示例

QAbstractTableModel

2 个答案:

答案 0 :(得分:4)

来自official documentation

  

实现基于表的模型时,rowCount()应在父项有效时返回0。

columnCount()也是如此。为完整起见,如果父级有效,data()应返回None


这是怎么回事:

  1. 点击“Stinkberries”旁边的“+”符号。
  2. QTreeView认为,“我需要扩展视图。我想知道'Stinkberries'下有多少行?”为了找到答案,QTreeView调用了rowCount(),并通过了作为父母的“Stinkberries”单元格的索引。
  3. FavoritesTableModel::rowCount()返回5,所以QTreeView认为,“啊,'Stinkberries'下有5行。”
  4. 列的过程相同。
  5. QTreeView决定检索“Stinkberries”下的第一个项目。它调用data(),传递第0行,第0列,以及“Stinkberries”单元格的索引作为父级。
  6. FavoritesTableModel::data()返回“苹果”,所以QTreeView认为,“啊,'Stinkberries'下的第一个项目是'苹果'。”
  7. 要获得正确的行为,您的代码必须为步骤#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 显示时才会出现这种情况(这通常是一个很好的假设)。