QTreeView 根据内容动态高度,显示三角形

QTreeView dynamic height according to content, disclosure triangle

我想用 QTreeWidget 模拟 disclosure triangle / disclosure widget。为此,我创建了一个只有一个顶级项目的 QTreeWidget。它的背景是透明的,它的 header 是不可见的。

这里是代码 (mwe):

import sys
from PySide2.QtWidgets import ( QApplication,
                                QLabel,
                                QTreeWidget,
                                QTreeWidgetItem, 
                                QVBoxLayout,
                                QWidget)


class DisclosureTree(QTreeWidget):

    def __init__(self):

        super().__init__()

        # Add content
        self.setColumnCount(1)
        parent_item = QTreeWidgetItem(self, ['Disclosure triangle'])
        self.addTopLevelItem(parent_item)
        parent_item.addChild(QTreeWidgetItem(parent_item, 'AAA'))
        parent_item.addChild(QTreeWidgetItem(parent_item, 'BBB'))
        parent_item.addChild(QTreeWidgetItem(parent_item, 'CCC'))

        # Cosmetics
        self.header().hide()
        self.setStyleSheet('background-color: transparent;')

if __name__ == '__main__':
    app = QApplication()

    vbox = QVBoxLayout()
    disclosuretree = DisclosureTree()
    label = QLabel('Plenty of space above…')
    vbox.addWidget(disclosuretree)
    vbox.addWidget(label)
    vbox.addStretch()

    widget = QWidget()
    widget.setLayout(vbox)
    widget.show()

    sys.exit(app.exec_())

问题是我希望小部件的高度在折叠或展开时自动调整大小,例如:

有人知道怎么做吗?非常感谢,如果我能提供帮助,请告诉我!

您必须根据其内容更新小部件的最大高度。对于每个顶部项目,您需要使用 rowHeight() 获取该行的高度,并在项目展开时递归地对子项目执行相同的操作。此外,您需要覆盖 sizeHintminimumSizeHint.

class DisclosureTree(QTreeWidget):
    def __init__(self):
        # ...
        self.expanded.connect(self.updateHeight)
        self.collapsed.connect(self.updateHeight)

    def updateHeight(self):
        self.setMaximumHeight(self.sizeHint().height())

    def getHeight(self, parent=None):
        height = 0
        if not parent:
            parent = self.rootIndex()
        for row in range(self.model().rowCount(parent)):
            child = self.model().index(row, 0, parent)
            height += self.rowHeight(child)
            if self.isExpanded(child) and self.model().hasChildren(child):
                    height += self.getHeight(child)
        return height

    def sizeHint(self):
        hint = super().sizeHint()
        hint.setHeight(self.getHeight() + self.frameWidth() * 2)
        return hint

    def minimumSizeHint(self):
        return self.sizeHint()