collapsiblewidget.cpp (2519B)
1 // https://stackoverflow.com/questions/32476006/how-to-make-an-expandable-collapsable-section-widget-in-qt 2 #include <QtCore/QPropertyAnimation> 3 4 #include "collapsiblewidget.h" 5 6 CollapsibleWidget::CollapsibleWidget(const QString& title, const int animationDuration, QWidget* parent) 7 : QWidget(parent), animationDuration(animationDuration) 8 { 9 toggleButton.setStyleSheet("QToolButton { border: none; }"); 10 toggleButton.setToolButtonStyle(Qt::ToolButtonTextBesideIcon); 11 toggleButton.setArrowType(Qt::ArrowType::RightArrow); 12 toggleButton.setText(title); 13 toggleButton.setCheckable(true); 14 toggleButton.setChecked(false); 15 16 contentArea.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 17 18 // start out collapsed 19 contentArea.setMaximumHeight(0); 20 contentArea.setMinimumHeight(0); 21 22 // let the entire widget grow and shrink with its content 23 toggleAnimation.addAnimation(new QPropertyAnimation(this, "minimumHeight")); 24 toggleAnimation.addAnimation(new QPropertyAnimation(this, "maximumHeight")); 25 toggleAnimation.addAnimation(new QPropertyAnimation(&contentArea, "maximumHeight")); 26 27 // don't waste space 28 mainLayout.setContentsMargins(0, 0, 0, 0); 29 mainLayout.addWidget(&toggleButton); 30 mainLayout.addWidget(&contentArea); 31 setLayout(&mainLayout); 32 QObject::connect(&toggleButton, &QToolButton::clicked, [this](const bool checked) { 33 toggleButton.setArrowType(checked ? Qt::ArrowType::DownArrow : Qt::ArrowType::RightArrow); 34 toggleAnimation.setDirection(checked ? QAbstractAnimation::Forward : QAbstractAnimation::Backward); 35 toggleAnimation.start(); 36 }); 37 } 38 39 void CollapsibleWidget::setContentLayout(QLayout* contentLayout) 40 { 41 delete contentArea.layout(); 42 contentArea.setLayout(contentLayout); 43 const auto collapsedHeight = sizeHint().height() - contentArea.maximumHeight(); 44 auto contentHeight = contentLayout->sizeHint().height(); 45 for (int i = 0; i < toggleAnimation.animationCount() - 1; ++i) 46 { 47 QPropertyAnimation* spoilerAnimation = static_cast<QPropertyAnimation*>(toggleAnimation.animationAt(i)); 48 spoilerAnimation->setDuration(animationDuration); 49 spoilerAnimation->setStartValue(collapsedHeight); 50 spoilerAnimation->setEndValue(collapsedHeight + contentHeight); 51 } 52 QPropertyAnimation* contentAnimation = 53 static_cast<QPropertyAnimation*>(toggleAnimation.animationAt(toggleAnimation.animationCount() - 1)); 54 contentAnimation->setDuration(animationDuration); 55 contentAnimation->setStartValue(0); 56 contentAnimation->setEndValue(contentHeight); 57 }