-
Notifications
You must be signed in to change notification settings - Fork 34
/
Section.py
117 lines (95 loc) · 5.07 KB
/
Section.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
'''
Elypson/qt-collapsible-section
(c) 2016 Michael A. Voelkel - [email protected]
This file is part of Elypson/qt-collapsible section.
Elypson/qt-collapsible-section is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, version 3 of the License, or
(at your option) any later version.
Elypson/qt-collapsible-section is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with Elypson/qt-collapsible-section. If not, see <http:#www.gnu.org/licenses/>.
'''
import PyQt5.QtCore as cr
import PyQt5.QtWidgets as wd
# import PyQt5.QtGui as gui
import sys
class Section(wd.QWidget):
def __init__(self, title="", animationDuration=100, parent=None):
super().__init__(parent)
self.animationDuration = animationDuration
self.toggleButton = wd.QToolButton(self)
self.headerLine = wd.QFrame(self)
self.toggleAnimation = cr.QParallelAnimationGroup(self)
self.contentArea = wd.QScrollArea(self)
self.mainLayout = wd.QGridLayout(self)
self.toggleButton.setStyleSheet("QToolButton {border: none;}")
self.toggleButton.setToolButtonStyle(cr.Qt.ToolButtonTextBesideIcon)
self.toggleButton.setArrowType(cr.Qt.RightArrow)
self.toggleButton.setText(title)
self.toggleButton.setCheckable(True)
self.toggleButton.setChecked(False)
self.headerLine.setFrameShape(wd.QFrame.HLine)
self.headerLine.setFrameShadow(wd.QFrame.Sunken)
self.headerLine.setSizePolicy(wd.QSizePolicy.Expanding, wd.QSizePolicy.Maximum)
# self.contentArea.setLayout(wd.QHBoxLayout())
self.contentArea.setSizePolicy(wd.QSizePolicy.Expanding, wd.QSizePolicy.Fixed)
# start out collapsed
self.contentArea.setMaximumHeight(0)
self.contentArea.setMinimumHeight(0)
# let the entire widget grow and shrink with its content
self.toggleAnimation.addAnimation(cr.QPropertyAnimation(self, b"minimumHeight"))
self.toggleAnimation.addAnimation(cr.QPropertyAnimation(self, b"maximumHeight"))
self.toggleAnimation.addAnimation(cr.QPropertyAnimation(self.contentArea, b"maximumHeight"))
self.mainLayout.setVerticalSpacing(0)
self.mainLayout.setContentsMargins(0, 0, 0, 0)
row = 0
self.mainLayout.addWidget(self.toggleButton, row, 0, 1, 1, cr.Qt.AlignLeft)
self.mainLayout.addWidget(self.headerLine, row, 2, 1, 1)
self.mainLayout.addWidget(self.contentArea, row+1, 0, 1, 3)
self.setLayout(self.mainLayout)
self.toggleButton.toggled.connect(self.toggle)
def setContentLayout(self, contentLayout):
layout = self.contentArea.layout()
del layout
self.contentArea.setLayout(contentLayout)
collapsedHeight = self.sizeHint().height() - self.contentArea.maximumHeight()
contentHeight = contentLayout.sizeHint().height()
for i in range(0, self.toggleAnimation.animationCount()-1):
SectionAnimation = self.toggleAnimation.animationAt(i)
SectionAnimation.setDuration(self.animationDuration)
SectionAnimation.setStartValue(collapsedHeight)
SectionAnimation.setEndValue(collapsedHeight + contentHeight)
contentAnimation = self.toggleAnimation.animationAt(self.toggleAnimation.animationCount() - 1)
contentAnimation.setDuration(self.animationDuration)
contentAnimation.setStartValue(0)
contentAnimation.setEndValue(contentHeight)
def toggle(self, collapsed):
if collapsed:
self.toggleButton.setArrowType(cr.Qt.DownArrow)
self.toggleAnimation.setDirection(cr.QAbstractAnimation.Forward)
else:
self.toggleButton.setArrowType(cr.Qt.RightArrow)
self.toggleAnimation.setDirection(cr.QAbstractAnimation.Backward)
self.toggleAnimation.start()
if __name__ == '__main__':
class Window(wd.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
section = Section("Section", 100, self)
anyLayout = wd.QVBoxLayout()
anyLayout.addWidget(wd.QLabel("Some Text in Section", section))
anyLayout.addWidget(wd.QPushButton("Button in Section", section))
section.setContentLayout(anyLayout)
self.place_holder = wd.QWidget() # placeholder widget, only used to get acces to wd.QMainWindow functionalities
mainLayout = wd.QHBoxLayout(self.place_holder)
mainLayout.addWidget(section)
mainLayout.addStretch(1)
self.setCentralWidget(self.place_holder)
app = wd.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())