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
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
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?