def __init__(self, parent=None, title='', animationDuration=300): """ References: # Adapted from c++ version http://stackoverflow.com/questions/32476006/how-to-make-an-expandable-collapsable-section-widget-in-qt """ super(Spoiler, self).__init__(parent=parent) self.animationDuration = 300 self.toggleAnimation = QtCore.QParallelAnimationGroup() self.contentArea = QtWidgets.QScrollArea() self.headerLine = QtWidgets.QFrame() self.toggleButton = QtWidgets.QToolButton() self.mainLayout = QtWidgets.QGridLayout() toggleButton = self.toggleButton toggleButton.setStyleSheet("QToolButton { border: none; }") toggleButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) toggleButton.setArrowType(QtCore.Qt.RightArrow) toggleButton.setText(str(title)) toggleButton.setCheckable(True) toggleButton.setChecked(False) headerLine = self.headerLine headerLine.setFrameShape(QtWidgets.QFrame.HLine) headerLine.setFrameShadow(QtWidgets.QFrame.Sunken) headerLine.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Maximum) self.contentArea.setStyleSheet("QScrollArea { background-color: white; border: none; }") self.contentArea.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) # start out collapsed self.contentArea.setMaximumHeight(0) self.contentArea.setMinimumHeight(0) # let the entire widget grow and shrink with its content toggleAnimation = self.toggleAnimation toggleAnimation.addAnimation(QtCore.QPropertyAnimation(self, b"minimumHeight")) toggleAnimation.addAnimation(QtCore.QPropertyAnimation(self, b"maximumHeight")) toggleAnimation.addAnimation(QtCore.QPropertyAnimation(self.contentArea, b"maximumHeight")) # don't waste space mainLayout = self.mainLayout mainLayout.setVerticalSpacing(0) mainLayout.setContentsMargins(0, 0, 0, 0) row = 0 mainLayout.addWidget(self.toggleButton, row, 0, 1, 1, QtCore.Qt.AlignLeft) mainLayout.addWidget(self.headerLine, row, 2, 1, 1) row += 1 mainLayout.addWidget(self.contentArea, row, 0, 1, 3) self.setLayout(self.mainLayout) def start_animation(checked): arrow_type = QtCore.Qt.DownArrow if checked else QtCore.Qt.RightArrow direction = QtCore.QAbstractAnimation.Forward if checked else QtCore.QAbstractAnimation.Backward toggleButton.setArrowType(arrow_type) self.toggleAnimation.setDirection(direction) self.toggleAnimation.start() self.toggleButton.clicked.connect(start_animation)
def __init__(self, title="", parent=None): super(CollapsibleBox, self).__init__(parent) self.toggle_button = QtWidgets.QToolButton( text=title, checkable=True, checked=False ) self.toggle_button.setStyleSheet("QToolButton { border: none; }") self.toggle_button.setToolButtonStyle( QtCore.Qt.ToolButtonTextBesideIcon ) self.toggle_button.setArrowType(QtCore.Qt.RightArrow) self.toggle_button.pressed.connect(self.on_pressed) self.toggle_animation = QtCore.QParallelAnimationGroup(self) self.content_area = QtWidgets.QScrollArea( maximumHeight=0, minimumHeight=0 ) self.content_area.setSizePolicy( QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed ) self.content_area.setFrameShape(QtWidgets.QFrame.NoFrame) lay = QtWidgets.QVBoxLayout(self) lay.setSpacing(0) lay.setContentsMargins(0, 0, 0, 0) lay.addWidget(self.toggle_button) lay.addWidget(self.content_area) self.toggle_animation.addAnimation( QtCore.QPropertyAnimation(self, b"minimumHeight") ) self.toggle_animation.addAnimation( QtCore.QPropertyAnimation(self, b"maximumHeight") ) self.toggle_animation.addAnimation( QtCore.QPropertyAnimation(self.content_area, b"maximumHeight") )