You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QTreeView结合QSortFilterProxyModel插入三级子项失败问题

问题根源分析

你的问题出在TreeItem类的childNumber()方法上,这个方法的逻辑完全写反了,导致TreeModel无法正确生成父节点的索引,当添加三级子项时,模型无法识别正确的层级关系,所以新插入的项无法显示。

看一下你原来的childNumber()代码:

def childNumber(self):
    if self.parentItem is None:
        return self.parentItem.childItems.index(self)
    return 0

这里有两个严重错误:

  1. 当self.parentItem为None时(也就是根节点),你试图访问parentItem.childItems,这会直接抛出AttributeError,因为None没有childItems属性。
  2. 当当前项有父节点时,你错误地返回0,而正确的逻辑应该是返回当前项在父节点的子列表中的位置索引。
修正方案

把TreeItem类中的childNumber()方法替换为以下正确实现:

def childNumber(self):
    if self.parentItem is not None:
        return self.parentItem.childItems.index(self)
    return 0

这个修正做了两件事:

  • 当当前项有父节点时,正确获取它在父节点子列表中的位置,这样TreeModel的parent()方法就能生成正确的父索引。
  • 当当前项是根节点(parentItem为None)时,返回0,符合根节点的层级逻辑。
验证修正效果

按照你的测试步骤重新操作:

  1. 点击任意一级项
  2. 点击“Add row”按钮添加二级子项
  3. 点击新创建的二级项
  4. 再次点击“Add row”按钮
    此时你会看到三级子项正常显示,完全符合预期结果。
完整修正后的TreeItem.py代码
class TreeItem(object):
    ind_column_name = 0
    ind_column_id = 1
    ind_column_parent_id = 2
    key_name = "name"
    key_id = "id"
    key_parent_id = "parent"
    key_new_id = "new_item_id"

    def __init__(self, data, parent=None):
        self.parentItem = parent
        self.itemData = data
        self.childItems = []

    def child(self, row):
        try:
            return self.childItems[row]
        except IndexError:
            return ""

    def childCount(self):
        return len(self.childItems)

    def childNumber(self):
        if self.parentItem is not None:
            return self.parentItem.childItems.index(self)
        return 0

    def columnCount(self):
        return len(self.itemData)

    def data(self, column):
        if column != self.ind_column_id and column != self.ind_column_parent_id:
            return self.itemData[column]
        return None

    def id_data(self, column):
        if column == self.ind_column_id or column == self.ind_column_parent_id:
            return self.itemData[column]

    def insertChildren(self, position, count, columns):
        if position < 0 or position > len(self.childItems):
            return False
        for row in range(count):
            data = [None for v in range(columns)]
            item = TreeItem(data, self)
            self.childItems.insert(position, item)
        return True

    def insertColumns(self, position, columns):
        if position < 0 or position > len(self.itemData):
            return False
        for column in range(columns):
            self.itemData.insert(position, None)
        for child in self.childItems:
            child.insertColumns(position, columns)
        return True

    def parent(self):
        return self.parentItem

    def removeChildren(self, position, count):
        if position < 0 or position + count > len(self.childItems):
            return False
        for row in range(count):
            self.childItems.pop(position)
        return True

    def removeColumns(self, position, columns):
        if position < 0 or position + columns > len(self.itemData):
            return False
        for column in range(columns):
            self.itemData.pop(position)
        for child in self.childItems:
            child.removeColumns(position, columns)
        return True

    def setData(self, column, value):
        if column < 0 or column >= len(self.itemData):
            return False
        self.itemData[column] = value
        return True

    def to_json(self):
        parent_id = self.itemData[self.ind_column_parent_id]
        item_id = self.itemData[self.ind_column_id]
        json_data = dict()
        json_data[self.key_name] = self.itemData[self.ind_column_name]
        if parent_id is not None:
            json_data[self.key_parent_id] = parent_id
        if item_id is not None:
            json_data[self.key_id] = item_id
        return json_data

内容的提问来源于stack exchange,提问作者Sergey Maslov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:39:52