PyQT - Collapsible Sections

10/15/2023, Sun
Categories: #python
Tags: #pyqt

PyQt - Accordion Equivalent

When there are groups of related information that are to be made available for viewing, but is too visually cluttering when shown all at once, one can use the grouping behavior of an accordion or collapsible section to selectively show information.

One native Qt widget that can be used in PyQT is the QtToolBox. This widget offers a vertical list of collapsible containers where only one can be viewed at a time. It behaves similar to a tab view except the the tab and its associated content are bunched together.

import sys

from PyQt6.QtWidgets import QApplication, QLabel, QMainWindow, QToolBox, QGridLayout, QLabel, QPushButton, QWidget

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(500, 300)

        # Create layouts
        layout = QGridLayout()
        bees_layout = QGridLayout()
        
        # Create toolbox widget
        toolbox = QToolBox()

        # Add the labels to the toolbox
        # to create each section
        toolbox.addItem(QLabel("Some information about ants."), "Ants")

        btn = QPushButton('A button for bees')
        widget = QWidget(self)
        widget.setLayout(bees_layout)
        bees_layout.addWidget(btn)
        toolbox.addItem(widget, "Bees")

        # Set the widget to the layout
        layout.addWidget(toolbox)
        self.setCentralWidget(toolbox)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())
example of qtoolbox

One limitation of the QtToolBox is that only one group can be visible at once, but one might want to show multiple groups at once. To remedy this problem, use the superqt QCollapsible component .

Below example adapted from superqt's documentation page.

import sys

from PyQt6.QtWidgets import QApplication, QLabel, QPushButton, QLabel, QPushButton, QWidget, QVBoxLayout, QMainWindow

from superqt import QCollapsible

class MainWindow(QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.initUI()

    def initUI(self):

        # Create layouts
        QMainWindow().setCentralWidget(QWidget())
        layout = QVBoxLayout()

        # Create the collapsible sections
        collapsible = QCollapsible("Advanced analysis")
        collapsible2 = QCollapsible("Some other analysis")

        layout.addWidget(collapsible)
        layout.addWidget(collapsible2)

        # Add contents to the collapsible sections
        collapsible.addWidget(
            QLabel("This is the inside of the collapsible frame"))
        for i in range(10):
            collapsible.addWidget(QPushButton(f"Content button {i + 1}"))

        collapsible2.addWidget(QLabel("Another note"))

        # Show the collapsible sections
        collapsible.expand(animate=True)
        collapsible.show()
        collapsible2.expand(animate=True)
        collapsible2.show()

        # Display layouts
        self.setLayout(layout)
        self.show()

if __name__ == '__main__':
    app = QApplication([])
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec())
example of superqt qcollapsible