首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QTreeWidget:如何动态地改变sizeHint?

QTreeWidget:如何动态地改变sizeHint?
EN

Stack Overflow用户
提问于 2021-05-27 07:38:23
回答 1查看 376关注 0票数 0

我有一个QTreeWidget,其中TopLevelIteps被一个自定义小部件替换。Said小部件有一个QStateMachine.动画的最大和最小高度

QTreeWidget (全球综合框架):

自定义Widget动画(GIF):

问题是,当自定义小部件展开时,行将不会调整其高度以适应它:

行高固定尺寸(GIF):

导致小部件项之间的重叠,而不是像这样互相推开:

我想要的结果(GIF):

我尝试在顶级项上使用setSizeHint(),但是它在项/小部件之间创建了一个很大的空空间:

使用setSizeHint()(GIF):

我在想,也许我必须实现sizeHint(),但我不太确定应该把什么放在那里。还是有更好的方法来解决这个问题?

我真的很感激你给我一些提示。

示例代码:

代码语言:javascript
复制
# Custom Widget
class ExpandableFrame(QFrame):

    def __init__(self):
        QFrame.__init__(self)

        # Default Properties
        self.setFixedSize(200,50)
        self.setStyleSheet('background-color: #2e4076; border: 2px solid black; border-radius: 10px;')
     
        # Setup expand button
        self.expandToggle = QToolButton()
        self.expandToggle.setText('[]')
        self.expandToggle.setMaximumSize(10,20)
        self.expandToggle.setCursor(Qt.PointingHandCursor)

        # Setup layout
        layout = QHBoxLayout()
        layout.setAlignment(Qt.AlignRight)
        layout.addWidget(self.expandToggle)
        self.setLayout(layout)

        self.expandArea()

    # Animates minimumHeight and maximumHeight
    def expandArea(self):

        heigth = self.height()
        newHeigth = 100

        machine = QStateMachine(self)

        state1 = QState()
        state1.assignProperty(self, b'minimumHeight', heigth)
        state1.assignProperty(self, b'maximumHeight', heigth)

        state2 = QState()
        state2.assignProperty(self, b'minimumHeight', newHeigth)
        state2.assignProperty(self, b'maximumHeight', newHeigth)

        # Create animations
        expandAnim = QPropertyAnimation(self, 'minimumHeight')
        closeAnim = QPropertyAnimation(self, 'maximumHeight')
        expandAnim.setDuration(125)
        closeAnim.setDuration(125)
        expandAnim.setEasingCurve(QEasingCurve.Linear)  

        # Create event transitions
        eventTransition1 = QEventTransition(self.expandToggle, QEvent.MouseButtonPress)
        eventTransition1.setTargetState(state2)
        eventTransition1.addAnimation(expandAnim)
        state1.addTransition(eventTransition1)

        eventTransition2 = QEventTransition(self.expandToggle, QEvent.MouseButtonPress)
        eventTransition2.setTargetState(state1)
        eventTransition2.addAnimation(closeAnim)
        state2.addTransition(eventTransition2)
        
        # Add the states to the machine
        machine.addState(state1)
        machine.addState(state2)
        machine.setInitialState(state1)
        machine.start()
    
# Tree Widget
class CustomTree(QTreeWidget):

    customWidget = []

    def __init__(self, parent=None):
        QTreeWidget.__init__(self, parent)

        # Create top level items
        itemCount = 3
        for element in range(itemCount):
            topLevelItem = QTreeWidgetItem()
            self.addTopLevelItem(topLevelItem)

            # Replace the top level items with the expandable custom widget:
            # Get the Model Index to each item
            modelIndex = self.indexFromItem(topLevelItem, 0)
            
            # Create the ExpandableFrame widgets for all the top level items
            self.customWidget.append(ExpandableFrame())

            # Set the widget to each top level item based on its index
            self.setIndexWidget(modelIndex, self.customWidget[element])
            
            # Create more items and add them as children of the top level items
            for x in range(itemCount):
                child = QTreeWidgetItem()
                child.setText(0,'Child')
                topLevelItem.addChild(child)

这个例子是这样的:

运行的最小代码示例:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-28 06:11:56

一种解决方案是,每次更改任何小部件的大小时,都会发出视图项委托的sizeHintChanged信号。这说明应该更新项目的位置。要实现这一点,您可以覆盖resizeEvent of ExpandableFrame并发出自定义信号。

代码语言:javascript
复制
class ExpandableFrame(QFrame):
    resized = pyqtSignal(QVariant)

    def resizeEvent(self, event):
        self.resized.emit(self.height())
        super().resizeEvent(event)

CustomTree中,您可以通过重写setIndexWidgetExpandableFrame.resized连接到自定义树的委托的sizeHintChanged信号。

代码语言:javascript
复制
class CustomTree(QTreeWidget):
    ...

    def setIndexWidget(self, index, widget):
        super().setIndexWidget(index, widget)
        if isinstance(widget, ExpandableFrame):
            widget.resized.connect(lambda: self.itemDelegate().sizeHintChanged.emit(index))

屏幕截图:

这种方法的缺点是,如果移动或替换了小部件,则需要更新连接。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67717693

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档