3

我有一个 PyQt QTableView,连接到 a QAbstractTableModel,它本身连接到一个管理项目列表的自定义类。我可以在列表的末尾插入一个项目,它会适当地通知我的模型,然后调用beginInsertRowsand endInsertRows。我可以验证它是否调用了这两个函数,并且列表已自行更新,但表从未调用data来检索更新的行。

这是怎么回事?我该如何解决?

class FigureTableModel(QAbstractTableModel):
    def __init__(self):
        QAbstractTableModel.__init__(self)

        def changed(index):
            start_index = self.createIndex(index, 0)
            end_index = self.createIndex(index, COLUMNS - 1)
            self.dataChanged.emit(start_index, end_index)

        def adding_row(index):
            self.beginInsertRows(self.createIndex(0, 0), index, index)
            print 'adding ', index

        def added_row(index):
            self.endInsertRows()
            print 'added'

        figures.dataChanged.connect(changed)
        figures.rowAdding.connect(adding_row)
        figures.rowAdded.connect(added_row)

    def rowCount(self, parent):
        return len(figures)

    def columnCount(self, parent):
        return COLUMNS

    def data(self, index, role):
        print 'in data'
        if not index.isValid():
            return EMPTY

        return figures[index.row()].get_table_item(index.column(), role)
4

1 回答 1

3

有一个问题,我认为这是您的问题的原因。这是关于线:

self.beginInsertRows(self.createIndex(0, 0), index, index)

self.createIndex(0, 0)将创建一个有效的QModelIndex. 那是指parentin beginInsertRows,因此您基本上是在告诉视图您将在表的第一行中添加一个子项。由于该表没有子项的概念(它不是分层的),因此它什么也不做。

对于一个表,parent应该是一个 invalid QModelIndex,这意味着你的项目是在根。所以,你应该使用:

self.beginInsertRows(QtCore.QModelIndex(), index, index)
# or depending on how you import
self.beginInsertRows(QModelIndex(), index, index)

话虽如此,有几件事让我感到奇怪。

首先,在index方法之外,您通常应该避免直接调用createIndex。否则很容易把事情搞砸。index方法本身应该提供创建QModelIndex实例的一致方式。在您的情况下,由于您 inherit QAbstractTableModelindex方法已经实现。

其次,您正在使用全局变量。很多。这通常被认为是不好的做法。如果您的班级需要它们,请将它们传递给__init__. 例如,现在你不能实例化两个独立的模型。因为它们都将使用相同的全局figure变量。或者,我不知道EMPTY指的是什么,但data应该简单地返回None无效类型。不需要另一个名字。同样,您应该能够从中获取COLUMNSfigures或者如果您需要显式值,则应该将其传递给__init__.

于 2012-10-29T02:08:15.687 回答