My problem is that collapsible QToolButton
is acting weird in QScrollArea
. It's not my first problem with collapsible QToolButton
and at first it was my layout not stretching , so I added stretching(addStretch(1)
) and it started working fine. Today, I tried to add QScrollArea
to layout and then adding QToolButtons
with widgets under it and same looking problem started again. So I thought that is again problem with stretching , so I was trying to search way of stretching QScrollArea
and after looking, tried setting setSizePolicy()
, sizeHint()
, but it wouldn't fix problem. Can somebody help me find problem ?
More detailed explanation of problem : when you are expanding all collapsible QToolButton
's first time there is no problem , but when you close them all and start opening again , starting from second QToolButton they start not opening from first few clicks. Also, I don't know if it's problem or not , but at first when you expand those buttons out of UI , they start shaking back and forward a little, basically not opening smoothly.
Here is code:
import random
from PySide2.QtGui import QPixmap, QBrush, QColor, QIcon, QPainterPath, QPolygonF, QPen, QTransform
from PySide2.QtCore import QSize, Qt, Signal, QPointF, QRect, QPoint, QParallelAnimationGroup, QPropertyAnimation, QAbstractAnimation
from PySide2.QtWidgets import QMainWindow, QDialog, QVBoxLayout, QHBoxLayout, QGraphicsView, QGraphicsScene, QFrame, \
QSizePolicy, QGraphicsPixmapItem, QApplication, QRubberBand, QMenu, QMenuBar, QTabWidget, QWidget, QPushButton, \
QSlider, QGraphicsPolygonItem, QToolButton, QScrollArea, QLabel
extraDict = {'buttonSetA': ['test'], 'buttonSetB': ['test'], 'buttonSetC': ['test'], 'buttonSetD': ['test']}
class MainWindow(QDialog):
def __init__(self, parent=None):
QDialog.__init__(self, parent=parent)
self.create()
def create(self, **kwargs):
main_layout = QVBoxLayout()
tab_widget = QTabWidget()
main_layout.addWidget(tab_widget)
tab_extra = QWidget()
tab_widget.addTab(tab_extra, 'Extra')
tab_main = QWidget()
tab_widget.addTab(tab_main, 'Main')
tab_extra.layout = QVBoxLayout()
tab_extra.setLayout(tab_extra.layout)
scroll = QScrollArea()
content_widget = QWidget()
scroll.setWidget(content_widget)
scroll.setWidgetResizable(True)
#scroll.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
tab_extra.layout.addWidget(scroll)
content_layout = QVBoxLayout(content_widget)
for name in extraDict.keys():
box = CollapsibleBox(name)
content_layout.addWidget(box)
box_layout = QVBoxLayout()
for j in range(8):
label = QLabel("{}".format(j))
color = QColor(*[random.randint(0, 255) for _ in range(3)])
label.setStyleSheet("background-color: {}; color : white;".format(color.name()))
label.setAlignment(Qt.AlignCenter)
box_layout.addWidget(label)
box.setContentLayout(box_layout)
content_layout.addStretch(1)
self.setLayout(main_layout)
class CollapsibleBox(QWidget):
def __init__(self, name):
super(CollapsibleBox, self).__init__()
self.toggle_button = QToolButton(text=name, checkable=True, checked=False)
self.toggle_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.toggle_button.setArrowType(Qt.RightArrow)
self.toggle_button.pressed.connect(self.on_pressed)
self.toggle_animation = QParallelAnimationGroup(self)
self.content_area = QScrollArea(maximumHeight=0, minimumHeight=0)
self.content_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.content_area.setFrameShape(QFrame.NoFrame)
lay = 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(QPropertyAnimation(self, b"minimumHeight"))
self.toggle_animation.addAnimation(QPropertyAnimation(self, b"maximumHeight"))
self.toggle_animation.addAnimation(QPropertyAnimation(self.content_area, b"maximumHeight"))
def on_pressed(self):
checked = self.toggle_button.isChecked()
self.toggle_button.setArrowType(Qt.DownArrow if not checked else Qt.RightArrow)
self.toggle_animation.setDirection(QAbstractAnimation.Forward
if not checked
else QAbstractAnimation.Backward
)
self.toggle_animation.start()
def setContentLayout(self, layout):
lay = self.content_area.layout()
del lay
self.content_area.setLayout(layout)
collapsed_height = (self.sizeHint().height() - self.content_area.maximumHeight())
content_height = layout.sizeHint().height()
for i in range(self.toggle_animation.animationCount()):
animation = self.toggle_animation.animationAt(i)
animation.setDuration(500)
animation.setStartValue(collapsed_height)
animation.setEndValue(collapsed_height + content_height)
content_animation = self.toggle_animation.animationAt(self.toggle_animation.animationCount() - 1)
content_animation.setDuration(500)
content_animation.setStartValue(0)
content_animation.setEndValue(content_height)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.setGeometry(500, 100, 500, 500)
window.show()
sys.exit(app.exec_())
Edit :
Here is link to a small video with problem I recorded , for more clear picture. (problem start on 0:12) I noticed problem occurs only when I open all QToolBox and then close it one by one from below and then start to open them again.