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

PyQt5 QTreeView无法展开孙级节点问题求助

PyQt树形视图展开/折叠功能修复方案

问题分析

你的代码存在两个核心问题导致子节点无法展开:

  1. 方法调用笔误:MainWindow中调用了不存在的add_group方法,实际模型中定义的是add_items,导致数据未正确加载(若你本地代码是笔误则忽略,但需确保调用正确)。
  2. 树形结构构建错误:不同层级的节点被分散到不同列中,导致点击子节点列(如Variant、Colour)时,对应的索引节点没有挂载子节点,无法触发展开/折叠;同时点击事件未处理跨列点击的情况。

修复步骤及代码

1. 修正方法调用笔误

将MainWindow中的model.add_group(key, item)改为model.add_items(key, item)。

2. 调整树形结构构建逻辑

把每个层级的节点作为整行添加到父节点下,确保子节点正确挂载到父节点的行结构中。

3. 优化点击事件处理

确保点击任意列都能触发对应行第一列节点的展开/折叠。

以下是修复后的完整代码:

from PyQt5 import QtCore, QtGui, QtWidgets

class GroupView(QtWidgets.QTreeView):
    def __init__(self, model, parent=None):
        super(GroupView, self).__init__(parent)
        self.setIndentation(20)  # 恢复缩进,方便区分层级
        self.clicked.connect(self.on_clicked)
        self.setModel(model)
        self.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

    @QtCore.pyqtSlot(QtCore.QModelIndex)
    def on_clicked(self, index):
        # 获取当前行第一列的索引,确保点击任意列都操作行的根节点
        first_col_index = index.sibling(index.row(), 0)
        self.setExpanded(first_col_index, not self.isExpanded(first_col_index))
            
class GroupModel(QtGui.QStandardItemModel):
    def __init__(self, parent=None):
        super(GroupModel, self).__init__(parent)
        self.setColumnCount(5)
        self.setHorizontalHeaderLabels(["Name", "Variant", "Colour", "Size", "Stock"])

    def add_items(self, key, item):
        root_item = self.invisibleRootItem()
        root_item.setEditable(False)
        
        # 构建根节点行(产品名称层级)
        root_row = [
            QtGui.QStandardItem(key),
            QtGui.QStandardItem(),
            QtGui.QStandardItem(),
            QtGui.QStandardItem(),
            QtGui.QStandardItem(str(item['total']))
        ]
        for cell in root_row:
            cell.setEditable(False)
        root_item.appendRow(root_row)
        product_item = root_row[0]
        
        # 添加Variant层级
        for key1, item1 in item['var'].items():
            variant_row = [
                QtGui.QStandardItem(),
                QtGui.QStandardItem(key1),
                QtGui.QStandardItem(),
                QtGui.QStandardItem(),
                QtGui.QStandardItem(str(item1['total']))
            ]
            for cell in variant_row:
                cell.setEditable(False)
            product_item.appendRow(variant_row)
            variant_item = variant_row[1]
            
            # 添加Colour层级
            for key2, item2 in item1['colour'].items():
                colour_row = [
                    QtGui.QStandardItem(),
                    QtGui.QStandardItem(),
                    QtGui.QStandardItem(key2),
                    QtGui.QStandardItem(),
                    QtGui.QStandardItem(str(item2['total']))
                ]
                for cell in colour_row:
                    cell.setEditable(False)
                variant_item.appendRow(colour_row)
                colour_item = colour_row[2]
                
                # 添加Size层级
                for key3, item3 in item2['size'].items():
                    size_row = [
                        QtGui.QStandardItem(),
                        QtGui.QStandardItem(),
                        QtGui.QStandardItem(),
                        QtGui.QStandardItem(key3),
                        QtGui.QStandardItem(str(item3))
                    ]
                    for cell in size_row:
                        cell.setEditable(False)
                    colour_item.appendRow(size_row)
                    
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        model = GroupModel(self)
        tree_view = GroupView(model)
        self.setCentralWidget(tree_view)
        
        product_dict = {
            'T-Shirt Minion': {
                'total': 510,
                'var': {
                    'Lengan Panjang': {
                        'total': 370,
                        'colour': {
                            'Merah': {
                                'total': 370,
                                'size': {'S': 100, 'L': 170, 'M': 100}
                            }
                        }
                    },
                    'Lengan Pendek': {
                        'total': 140,
                        'colour': {'Merah': {'total': 140, 'size': {}}}
                    }
                }
            }
        }
    
        for key, item in product_dict.items():
            model.add_items(key, item)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.resize(720, 400)
    w.show()
    sys.exit(app.exec_())

修复说明

  • 调整了树形结构的构建方式,每个层级的节点作为整行添加到父节点下,确保子节点正确挂载。
  • 修改点击事件,点击任意列都会触发对应行第一列节点的展开/折叠,符合Excel数据透视表的操作习惯。
  • 恢复了树形视图的缩进,让层级关系更清晰。

内容的提问来源于stack exchange,提问作者Anthony Lauly

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 14:03:23