在 QTreeView 中显示来自 QAbstractTableModel 的数据 [英] Display data from QAbstractTableModel in QTreeView

查看:36
本文介绍了在 QTreeView 中显示来自 QAbstractTableModel 的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

短版

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

详情

我试图在 QTreeViewQAbstractTableModel 中显示一些数据.在

完整的工作示例

from PySide import QtGui, QtCore食品类(对象):def __init__(self, name, shortDescription, note, parent = None):self.data = (name, shortDescription, note);self.parentIndex = 父类收藏表模型(QtCore.QAbstractTableModel):def __init__(self):QtCore.QAbstractTableModel.__init__(self)self.foods = []self.loadData()定义数据(自我,索引,角色= QtCore.Qt.DisplayRole):如果角色== QtCore.Qt.DisplayRole:返回 self.foods[index.row()].data[index.column()]返回无def rowCount(self, index=QtCore.QModelIndex()):返回 len(self.foods)def columnCount(self, index=QtCore.QModelIndex()):返回 3def index(self, row, column, parent = QtCore.QModelIndex()):返回 self.createIndex(row, column, parent)def loadData(self):allFoods=(苹果"、梨"、葡萄"、饼干"、草莓")allDescs = (红"、绿"、紫"、好吃"、嗯?")allNotes = ("最近买的", "有点好吃", "奇怪的酿酒葡萄",太好了……和牛奶一起吃"、别往鼻子里塞")对于名称、简短描述、zip 中的注释(allFoods、allDescs、allNotes):食物 = 食物(名称,简短描述,注释)self.foods.append(food)定义主():导入系统app = QtGui.QApplication(sys.argv)模型 = 收藏夹表模型()#表格视图view1 = QtGui.QTableView()view1.setModel(模型)view1.show()#树视图view2 = QtGui.QTreeView()view2.setModel(模型)view2.show()sys.exit(app.exec_())如果 __name__ == '__main__':主要的()

解决方案

来自 官方文档:

<块引用>

在实现基于表的模型时,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() 返回Apples",因此 QTreeView 认为,啊,'Stinkberries' 下的第一项是'Apples'."

要获得正确的行为,您的代码必须为第 3 步和第 4 步返回 0.

<小时>

最后,为了确保+"号根本不出现,让 hasChildren() 为每个单元格返回 false.

Short version

I am trying to display data from a QAbstracctTableModel in a QTreeView. When I do, I end up with the entire table displayed as the child of every node (and grandchild, and so-on). How can I display a treeview of an abstract table model?

Details

I am trying to display some data in a QAbstractTableModel in a QTreeView. In the Model-View Tutorial, after presenting an example QAbstractTableModel, it makes it seem it's as simple as replacing QTableView with QTreeView:

You can convert the example above into an application with a tree view. Simply replace QTableView with QTreeView, which results in a read/write tree. No changes have to be made to the model.

When I make this replacement, I do end up with a tree showing, but if I click on any of the icons to expand it (which should do nothing, as there is no hierarchy built in), Python crashes with Python.exe has stopped working. This has been brought up before ], but without a workable solution.

To try to fix this behavior, I reimplemented the index function in my QAbstractTableModel subclass (see full working example below). This leads to a very different type of error. Namely, every node in the tree now contains the entire table as data. No matter how many times I click, the entire table shows up. Like this:

I seem to be in some kind of recursive nightmare, and do not know how to escape. The related question below suggests I might have to go to QAbstractItemModel, but the tutorial quote above suggests otherwise (which states, No changes have to be made to the model).

Related question

QTreeView always displaying the same data

Full working example

from PySide import QtGui, QtCore

class Food(object):
    def __init__(self, name, shortDescription, note, parent = None):
        self.data = (name, shortDescription, note);
        self.parentIndex = parent

class FavoritesTableModel(QtCore.QAbstractTableModel):
    def __init__(self):
        QtCore.QAbstractTableModel.__init__(self)
        self.foods = []  
        self.loadData() 

    def data(self, index, role = QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole:
            return self.foods[index.row()].data[index.column()]
        return None

    def rowCount(self, index=QtCore.QModelIndex()):
        return len(self.foods)

    def columnCount(self, index=QtCore.QModelIndex()):
        return 3

    def index(self, row, column, parent = QtCore.QModelIndex()):  
        return self.createIndex(row, column, parent)

    def loadData(self):   
        allFoods=("Apples", "Pears", "Grapes", "Cookies", "Stinkberries")
        allDescs = ("Red", "Green", "Purple", "Yummy", "Huh?")
        allNotes = ("Bought recently", "Kind of delicious", "Weird wine grapes",
                    "So good...eat with milk", "Don't put in your nose")
        for name, shortDescription, note in zip(allFoods, allDescs, allNotes):
            food = Food(name, shortDescription, note)                                      
            self.foods.append(food) 

def main():
    import sys
    app = QtGui.QApplication(sys.argv)

    model = FavoritesTableModel() 

    #Table view
    view1 = QtGui.QTableView()
    view1.setModel(model)
    view1.show()

    #Tree view
    view2 = QtGui.QTreeView()
    view2.setModel(model)
    view2.show()

    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

解决方案

From the official documentation:

When implementing a table based model, rowCount() should return 0 when the parent is valid.

The same goes for columnCount(). And for completeness, data() should return None if the parent is valid.


What happened is this:

  1. You click on the '+' sign next to "Stinkberries".
  2. The QTreeView thinks, "I need to expand the view. I wonder how many rows exist under 'Stinkberries'?" To find out, the QTreeView calls rowCount(), and passes the index of the "Stinkberries" cell as the parent.
  3. FavoritesTableModel::rowCount() returns 5, so the QTreeView thinks, "Ah, there are 5 rows under 'Stinkberries'."
  4. The same process happens for columns.
  5. The QTreeView decides to retrieve the first item under "Stinkberries". It calls data(), passing Row 0, Column 0, and the index of the "Stinkberries" cell as the parent.
  6. FavoritesTableModel::data() returns "Apples", so the QTreeView thinks, "Ah, the first item under 'Stinkberries' is 'Apples'."
  7. etc.

To get correct behaviour, your code must return 0 for Steps #3 and #4.


Finally, to make sure that the '+' signs don't appear at all, make hasChildren() return false for every cell.

这篇关于在 QTreeView 中显示来自 QAbstractTableModel 的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆