0

I want to create a widget in PyQt5 that works as a "stacked submenu": once the user clicks on a specific label/row, a bunch of related options/widgets appear below. These submenus can be stacked on top of each other, like in the desired example below (a screenshot from LibreOffice Impress):

What I want

enter image description here

My current attempt is below: I'm using a QPushButton responsible for showing/hiding a QFrame containing arbitrary widgets. The basic idea is here, but this is sort of a "manual" approach.

What I got so far

enter image description here

The code

import sys

from PyQt5.QtWidgets import (QApplication, QFrame, QLabel, QPushButton,
                             QVBoxLayout, QWidget)


class MyApp(QWidget):
    def __init__(self):
        super().__init__(parent=None)

        # Layout
        layout = QVBoxLayout()
        self.setLayout(layout)

        # Row, widgets are placed in a frame below
        self.row = QPushButton('Graphs')
        layout.addWidget(self.row)

        # Frame where widgets are placed
        self.frame = QFrame()
        layout.addWidget(self.frame)

        # Add a layout and some widgets to the frame
        self.frame.setLayout(QVBoxLayout())
        self.frame.layout().addWidget(QLabel('Data 1'))
        self.frame.layout().addWidget(QLabel('Data 2'))
        self.frame.layout().addWidget(QPushButton('New Graph...'))
        self.frame.setVisible(False)

        # Show/hide frame when row is clicked
        self.row.clicked.connect(self.toggle_frame)

    def toggle_frame(self) -> None:
        if self.frame.isVisible():
            self.frame.setVisible(False)
        else:
            self.frame.setVisible(True)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    gui = MyApp()
    gui.show()
    sys.exit(app.exec_())

Maybe PyQt5 has a built-in way of creating such a submenu? I'm not sure what to even call such a design, so I'm having trouble looking for answers. I Tried messing with a QTreeWidget but I failed to find an option to show/hide all elements in the tree (and adding arbitrary widgets/layouts to a QTreeWidget seems a bit hacky). Or is my approach the way to go, just lacking a bit of styling/layout management?

jfaccioni
  • 7,099
  • 1
  • 9
  • 25
  • 1
    Something like this? [How to create collapsible box in PyQt](https://stackoverflow.com/a/52617714) – musicamante Apr 05 '21 at 17:17
  • @musicamante yes, exactly! Thanks a lot, I had no idea that this design was called "collapsible box". It worked perfectly for my needs :) – jfaccioni Apr 06 '21 at 02:33

0 Answers0