【问题标题】:pyqt treeview index error removing last rowpyqt树视图索引错误删除最后一行
【发布时间】:2014-12-28 02:21:05
【问题描述】:

我有一个简单的层次结构深度为 2 的 2 列 treeView;根>父>子。我的 treeView 子类中有一个 removeRows 调用,当按下删除键时会对其进行评估。当我删除除最后一行之外的任何行时,这似乎工作正常。

我收到一个IndexError: list index out of range,它似乎来自节点类child 方法。这似乎发生在模型的removeRows 中调用self.beginRemoveRows 方法时。奇怪的是,操作顺序似乎颠倒了,或者线程在模型知道它最近的更新之前以某种方式导致刷新发生。

通过这些代码 sn-ps,我希望有人可以提供可能的解释或一些想法,说明接下来要尝试什么来调试它。

来自 QTreeView 子类,

def keyPressEvent(self, event):
    if event.key() == Qt.Key_Delete:
        index = self.currentIndex()
        self.model().removeRow(index.row())
    else:
        # call base class keyPressEvent
        QTreeView.keyPressEvent(self, event)  

来自 QAbstractItemModel 子类,

def index(self, row, column, parent=QModelIndex()):
    parent_node = self.getNode(parent)
    child_item = parent_node.child(row)
    if child_item:
        return self.createIndex(row, column, child_item)
    else:
        return QModelIndex()

def getNode(self, index):
    if index.isValid():
        node = index.internalPointer()
        if node:
            return node
    return self._root

def removeRows(self, position, rows, parent=QModelIndex()):

    parent_node = self.getNode(parent)
    self.beginRemoveRows(parent, position, position + rows - 1)
    parent_node.removeChild(position)
    self.endRemoveRows()
    return True

来自节点类

def child(self, row):
    return self._children[row]

def removeChild(self, position):

    if position < 0 or position >= len(self._children):
        return False

    child = self._children.pop(position)
    child._parent = None

    return True

【问题讨论】:

  • 我想我通过在删除最后一个索引之前清除选择解决了这个问题。 treeView 试图选择其他内容,因为所选索引被删除并且在更新之前它没有更新 rowCount ...我想这可能是一个错误?
  • 你是怎么做到的?我试图做同样的事情无济于事。如果您已经解决了您的问题,您可以使用解决方案来回答并接受您自己的答案

标签: python treeview pyqt delete-row qabstractitemmodel


【解决方案1】:

我花了一些时间,但我终于找到了错误的原因:根据index方法中的mail,您应该在继续之前检查索引是否存在。烦人的是,它没有写在method description 中,也没有写在 qt4 或 qt5 文档中。

index方法的正确实现应该就行了:

def index(self, row, column, parent=QModelIndex()):
    if self.hasIndex(row, column, parentIndex):
        parent_node = self.getNode(parent) 
        child_item = parent_node.child(row)
        if child_item:
            return self.createIndex(row, column, child_item)
    else:
        return QModelIndex()

在我的应用程序中,这解决了这个问题。

【讨论】:

  • 不确定是否有人正在观看或将看到此内容,但只是想发布一下我刚刚发现的内容,它救了我的命。我遇到了同样的问题,这为我解决了。
【解决方案2】:

对 QTreeView 的这种更改似乎起到了作用。不过,我并不绝对肯定问题不是由其他原因引起的。

def keyPressEvent(self, event):
    if event.key() == Qt.Key_Delete:
        index = self.currentIndex()
        if not index.isValid(): return

        parent = index.parent()

        # adjust selection so refresh does not trigger IndexError 
        self.selectionModel().setCurrentIndex(self.indexAbove(index), QItemSelectionModel.ClearAndSelect)

        # remove selected
        self.model().removeRow(row, parent=parent)

        return

    # call base class keyPressEvent
    QTreeView.keyPressEvent(self, event)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多