PyQt/partner_625781186/2.折叠控件/收缩伸展控件.py
2018-03-22 13:12:45 +08:00

134 lines
5.3 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
@resource:http://stackoverflow.com/questions/32476006/how-to-make-an-expandable-collapsable-section-widget-in-qt
@description: 摘录自上方
@Created on none
@email: none
'''
from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Spoiler(QWidget):
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)
#if 此处可以跳过不看
self.groupBox = QtWidgets.QGroupBox(self)
self.groupBox.setGeometry(QtCore.QRect(210, 30, 95, 134))
self.groupBox.setObjectName("groupBox")
self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox)
self.verticalLayout.setObjectName("verticalLayout")
self.pushButton3 = QtWidgets.QPushButton(self.groupBox)
icon = QtGui.QIcon()
self.pushButton3.setIcon(icon)
self.pushButton3.setObjectName("pushButton3")
self.verticalLayout.addWidget(self.pushButton3)
self.pushButton2 = QtWidgets.QPushButton(self.groupBox)
self.pushButton2.setObjectName("pushButton2")
self.verticalLayout.addWidget(self.pushButton2)
self.label_2 = QtWidgets.QLabel(self.groupBox)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
self.pushButton = QtWidgets.QPushButton(self.groupBox)
self.pushButton.setIcon(icon)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
self.animationDuration = 300
self.toggleAnimation = QParallelAnimationGroup()
self.contentArea = QScrollArea()
self.headerLine = QFrame()
self.toggleButton = QToolButton()
self.mainLayout = QGridLayout()
toggleButton = self.toggleButton
toggleButton.setStyleSheet("QToolButton { border: none; }")
toggleButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
toggleButton.setArrowType(Qt.RightArrow)
toggleButton.setText(str(title))
toggleButton.setCheckable(True)
toggleButton.setChecked(False)
headerLine = self.headerLine
headerLine.setFrameShape(QFrame.HLine)
headerLine.setFrameShadow(QFrame.Sunken)
headerLine.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
#endif 以下开始为源代码
self.contentArea.setStyleSheet(
"QScrollArea { background-color: white; border: none; }")
self.contentArea.setSizePolicy(
QSizePolicy.Expanding, 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(
QPropertyAnimation(self, b"minimumHeight"))
toggleAnimation.addAnimation(
QPropertyAnimation(self, b"maximumHeight"))
toggleAnimation.addAnimation(
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, 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 = Qt.DownArrow if checked else Qt.RightArrow
direction = QAbstractAnimation.Forward if checked else QAbstractAnimation.Backward
toggleButton.setArrowType(arrow_type)
self.toggleAnimation.setDirection(direction)
self.toggleAnimation.start()
self.toggleButton.clicked.connect(start_animation)
def setContentLayout(self, contentLayout):
# Not sure if this is equivalent to self.contentArea.destroy()
self.contentArea.destroy()
self.contentArea.setLayout(contentLayout)
collapsedHeight = self.sizeHint().height() - self.contentArea.maximumHeight()
contentHeight = contentLayout.sizeHint().height()
for i in range(self.toggleAnimation.animationCount()-1):
spoilerAnimation = self.toggleAnimation.animationAt(i)
spoilerAnimation.setDuration(self.animationDuration)
spoilerAnimation.setStartValue(collapsedHeight)
spoilerAnimation.setEndValue(collapsedHeight + contentHeight)
contentAnimation = self.toggleAnimation.animationAt(
self.toggleAnimation.animationCount() - 1)
contentAnimation.setDuration(self.animationDuration)
contentAnimation.setStartValue(0)
contentAnimation.setEndValue(contentHeight)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
ui = Spoiler()
ui.setContentLayout(ui.verticalLayout)
ui.show()
sys.exit(app.exec_())