如何通过QAbstractItemModel删除QTreeView行?删除失败排查
问题根源:TreeModel未实现removeRow方法
嘿,我一眼就揪出问题啦——你的TreeModel继承自QAbstractItemModel,但完全没实现removeRow方法!Qt的模型视图框架里,QAbstractItemModel的默认removeRow只是个空架子,根本不会去修改你自定义的Node数据结构,所以你调用它之后,数据毫无变化,视图自然不会显示节点被删除。
解决方案:给TreeModel添加removeRow实现
你需要在TreeModel类里补上removeRow方法,让它调用你的Node类里的removeChild方法来实际删除节点,这样才能和模型的通知机制(beginRemoveRows/endRemoveRows)配合起来更新视图。
把这段代码加到TreeModel类中:
def removeRow(self, row, parent=QtCore.QModelIndex()): if not parent.isValid(): parent_node = self._rootNode else: parent_node = parent.internalPointer() # 调用Node类的removeChild方法删除对应行的节点 return parent_node.removeChild(row)
为什么原来的代码没效果?
你原来的代码里,虽然正确调用了beginRemoveRows和endRemoveRows(这两个方法是告诉视图“我要改数据啦,准备刷新”),但中间的model.removeRow(index.row(), parent=index.parent())根本没做实际的删除操作——默认的removeRow只会返回False,你打印的success结果应该也是False对吧?
补上removeRow实现后,这个方法会真正调用Node的removeChild删掉目标节点,同时beginRemoveRows和endRemoveRows会通知视图刷新,这样你就能看到Node 6 (delete me)被成功删除了。
验证修改后的效果
运行修改后的代码,你会发现:
- 控制台打印的
Removal was a succes?:会变成True - QTreeView里的
Node 6 (delete me)节点消失了,完全符合你的预期
内容的提问来源于stack exchange,提问作者fredrik
相关产品推荐
相关产品推荐

