0

I am just wondering how to add cascading menu by QCheckBOx in Pyqt so that for every selection, I can unfold, and get more options. This is my code below,

 class Example (QWidget):

    def __init__(self, fname):
        self.fname=fname
        super().__init__()
        self.initUI()

    def initUI(self):
        
        self.sheets= list(fname.keys())     
        print(self.sheets)

        self.cb1 = QCheckBox("Hello", self)
        self.cb2 = QCheckBox("You", self)
        self.cb3 = QCheckBox("Are", self)
        self.cb4 = QCheckBox("My", self)
        self.cb5 = QCheckBox("Sunshine", self)
        
                            
    

        self.resize(300,400)
        self.setWindowTitle('QCheckBox')


        formLayout = QFormLayout()
        groupBox = QGroupBox("This Is Group Box")
      
        formLayout.addRow(self.cb1)
        formLayout.addRow(self.cb2)
        formLayout.addRow(self.cb3)
        formLayout.addRow(self.cb4)
        formLayout.addRow(self.cb5)

So I have 5 select boxes,

enter image description here

But now for every box I want to add the cascading menu, just like the pic shows below

enter image description here

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • By "add the cascading menu", do you refer to https://stackoverflow.com/questions/52615115/how-to-create-collapsible-box-in-pyqt ? (I am a bit confused why @eyllanesc as the author of the answer did not link to it...?) I do not fully understand what your modification wishes of this code are and where you fail to modify it. – Christian Karcher Jan 06 '21 at 10:53
  • @ChristianKarcher I have only edited the current post but even for me it is not clear what the OP wants so I have not made a search for a possible solution, if the OP points out that this post is the answer then I will close it as a duplicate, do you do you think it's a duplicate? – eyllanesc Jan 06 '21 at 14:33
  • @eyllanesc I think that he wants your solution, but with checkboxes instead of toolbuttons,...? I will take your code, strip down all animation fancyness and will answer with a boiled down checkbox example from it. Frankly, this is mostly an excercice for me to better understand your code :) – Christian Karcher Jan 07 '21 at 06:37

1 Answers1

0

Based on the assumption that what you want is already presented in eyllanesc's example, but with checkboxes, here is a version of this code with checkboxes and without animations:

enter image description here

from PyQt5 import QtWidgets


class CollapsibleBox(QtWidgets.QWidget):
    def __init__(self, title=""):
        super().__init__()
        self.toggle_button = QtWidgets.QCheckBox(text=title)
        self.toggle_button.clicked.connect(self.on_clicked)

        self.content_area = QtWidgets.QScrollArea(maximumHeight=0, minimumHeight=0)
        self.content_area.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        self.content_area.setFrameShape(QtWidgets.QFrame.NoFrame)

        lay = QtWidgets.QVBoxLayout(self)
        lay.setSpacing(0)
        lay.setContentsMargins(0, 0, 0, 0)
        lay.addWidget(self.toggle_button)
        lay.addWidget(self.content_area)

    def on_clicked(self):
        # this is a bit hacky, I just expand the boxes to a max. size of 1000, which should fit most needs
        self.content_area.setMaximumHeight(self.toggle_button.isChecked() * 1000)


class MainUI(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        vlay = QtWidgets.QVBoxLayout()
        for i in range(3):
            # add checkboxes and fully collapsed layouts (containing only labels for demo)
            box = CollapsibleBox(f"Collapsible Box {i+1}")
            vlay.addWidget(box)
            lay = QtWidgets.QVBoxLayout()
            # add items to the collapsed layout
            for j in range(5):
                label = QtWidgets.QLabel("demo")
                lay.addWidget(label)
            box.content_area.setLayout(lay)
        vlay.addStretch()
        widget = QtWidgets.QWidget()
        widget.setLayout(vlay)
        self.setCentralWidget(widget)


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    w = MainUI()
    w.show()
    app.exec_()
Christian Karcher
  • 2,533
  • 1
  • 12
  • 17