Search code examples
pythonpyqt5

How can I put these buttons in PyQt5 on top of each other?


I would like these buttons to be stacked neatly but I cannot find a way to do it.

enter image description here

Provided below is the snippet of code from this specific tab that I am working on.

        # Create Buttons for Tab 2
        self.generate_lru_notes = QPushButton("Generate LRU Report")
        self.generate_lru_notes.setToolTip("Click me to Generate the LRU Report")
        self.generate_lru_notes.setFixedWidth(200)

        self.clear_lru_notes = QPushButton("Clear LRU Report Data")
        self.clear_lru_notes.setToolTip("Click me to Clear the LRU Report")
        self.clear_lru_notes.setFixedWidth(200)

        # Create Labels and Text Edits for tab 2
        self.lbl_investigation_notes = QLabel("LRU Investigation Notes: ")
        self.txt_investigation_notes = QTextEdit()
        self.txt_investigation_notes.setFixedWidth(350)
        self.txt_investigation_notes.setFixedHeight(150)

        self.lbl_rework_notes = QLabel("LRU Rework Notes: ")
        self.txt_rework_notes = QTextEdit()
        self.txt_rework_notes.setFixedWidth(350) 
        self.txt_rework_notes.setFixedHeight(150)

        self.lbl_sc_investigation_notes = QLabel("Sub-Component Investigation Notes: ")
        self.txt_sc_investigation_notes = QTextEdit()
        self.txt_sc_investigation_notes.setFixedWidth(350)
        self.txt_sc_investigation_notes.setFixedHeight(150)

        self.lbl_sc_rework_notes = QLabel("Sub-Component Rework Notes")
        self.txt_sc_rework_notes = QTextEdit()
        self.txt_sc_rework_notes.setFixedWidth(350)
        self.txt_sc_rework_notes.setFixedHeight(150)

        self.lbl_ad_sc_inv_notes = QLabel ("Additional Sub-Component Investigation Notes: ")
        self.txt_ad_sc_inv_notes = QTextEdit()
        self.txt_ad_sc_inv_notes.setFixedWidth(350)
        self.txt_ad_sc_inv_notes.setFixedHeight(150)

        self.lbl_ad_sc_rework_notes = QLabel("Additonal Sub-Component Rework Notes: ")
        self.txt_ad_sc_rework_notes = QTextEdit()
        self.txt_ad_sc_rework_notes.setFixedWidth(350)
        self.txt_ad_sc_rework_notes.setFixedHeight(150)

        # Add the form elements to the first Grid in Tab 2
        self.t2_grid1 = QGridLayout()
        self.t2_grid1.setSpacing(0)
        self.t2_grid1.setRowStretch(50, 1)
        self.t2_grid1.setColumnStretch(50, 1)
        self.t2_grid1.setContentsMargins(0, 0, 0, 0)

        # Add the form elements to the second Grid in Tab 2
        self.t2_grid2 = QGridLayout()
        self.t2_grid2.setSpacing(0)
        self.t2_grid2.setRowStretch(50, 1)
        self.t2_grid2.setColumnStretch(50, 1)
        self.t2_grid2.setContentsMargins(0, 0, 0, 0)

        # Add the form elements to the third Grid in Tab 2
        self.t2_grid3 = QGridLayout()
        self.t2_grid3.setSpacing(1)
        self.t2_grid3.setRowStretch(50, 1)
        self.t2_grid3.setColumnStretch(50, 1)
        self.t2_grid3.setContentsMargins(0, 0, 0, 0)

        # Add the form elements to the fourth Grid on Tab 2.

        self.t2_grid4 = QGridLayout()
        self.t2_grid4.setSpacing(0)
        self.t2_grid4.setRowStretch(50, 1)
        self.t2_grid4.setColumnStretch(50, 1)
        self.t2_grid4.setContentsMargins(0, 0, 0, 0)

        # Grid 1 for Tab 2
        self.t2_grid1.addWidget(self.lbl_investigation_notes, 0, 0, 1, 1, Qt.AlignTop | Qt.AlignBottom)
        self.t2_grid1.addWidget(self.txt_investigation_notes, 1, 0, 1, 1, Qt.AlignTop | Qt.AlignBottom)
        self.t2_grid1.addWidget(self.lbl_rework_notes, 0, 2, 1, 1, Qt.AlignTop | Qt.AlignBottom)
        self.t2_grid1.addWidget(self.txt_rework_notes, 1, 2, 1, 1, Qt.AlignTop | Qt.AlignBottom)
        self.t2_grid1.addWidget(self.generate_lru_notes, 1, 3, 1, 1, Qt.AlignTop | Qt.AlignLeft)
        self.t2_grid1.addWidget(self.clear_lru_notes, 2, 3, 1, 1, Qt.AlignTop | Qt.AlignLeft)

        # Grid 3 for Tab 2
        self.t2_grid3.addWidget(self.lbl_sc_investigation_notes, 0, 0, 1, 1, Qt.AlignTop | Qt.AlignBottom)
        self.t2_grid3.addWidget(self.txt_sc_investigation_notes, 1, 0, 1, 1, Qt.AlignTop | Qt.AlignBottom)
        self.t2_grid3.addWidget(self.lbl_sc_rework_notes, 0, 2, 1, 1, Qt.AlignTop| Qt.AlignBottom)
        self.t2_grid3.addWidget(self.txt_sc_rework_notes, 1, 2, 1, 1, Qt.AlignTop | Qt.AlignBottom)

        # Grid 4 for Tab 2
        self.t2_grid4.addWidget(self.lbl_ad_sc_inv_notes, 0, 0, 1, 1, Qt.AlignTop | Qt.AlignBottom)
        self.t2_grid4.addWidget(self.txt_ad_sc_inv_notes, 1, 0, 1, 1, Qt.AlignTop | Qt.AlignBottom)
        self.t2_grid4.addWidget(self.lbl_ad_sc_rework_notes, 0, 2, 1, 1, Qt.AlignTop | Qt.AlignBottom)
        self.t2_grid4.addWidget(self.txt_ad_sc_rework_notes, 1, 2, 1, 1, Qt.AlignTop | Qt.AlignBottom)

        # Set the layout for the LRU Info tab
        self.tab2_layout = QVBoxLayout(self.tab2)
        self.tab2_layout.addLayout(self.t2_grid1)
        self.tab2_layout.addLayout(self.t2_grid2)
        self.tab2_layout.addLayout(self.t2_grid3)
        self.tab2_layout.addLayout(self.t2_grid4)

I have tried to align the Buttons in the same column but different rows, however the other widgets in the same grid are affecting the spacing I believe. I have thought about creating another grid but the way this tabs layout is setup the buttons would be below where I want them to be, unless someone has a better explanation?


Solution

  • You need to use the rowSpan argument of addWidget() for the text edits, so that they can occupy two lines in the layout, and then properly use setRowStretch (it seems like you're inverting the argument, and the row is wrong) for the bottom line, so that it will expand vertically.

    Also note that:

    • you should only use the alignment argument when you specifically need it, and, in any case, with valid values (Qt.AlignTop | Qt.AlignBottom doesn't make any sense);
    • the setColumnStretch() is also wrong, if you want to align the layout to the left, use layout.setAlignment();
    • there's no point in specifying the row and column span if both are going to be 1;
            self.t2_grid1 = QGridLayout()
            self.t2_grid1.setSpacing(0)
            self.t2_grid1.setRowStretch(2, 1)
            self.t2_grid1.setAlignment(Qt.AlignLeft)
            self.t2_grid1.setContentsMargins(0, 0, 0, 0)
            ...
            self.t2_grid1.addWidget(self.lbl_investigation_notes, 0, 0)
            self.t2_grid1.addWidget(self.txt_investigation_notes, 1, 0, 2, 1)
            self.t2_grid1.addWidget(self.lbl_rework_notes, 0, 2)
            self.t2_grid1.addWidget(self.txt_rework_notes, 1, 2, 2, 1)
            self.t2_grid1.addWidget(self.generate_lru_notes, 1, 3, Qt.AlignTop)
            self.t2_grid1.addWidget(self.clear_lru_notes, 2, 3, Qt.AlignTop)
    

    I suggest you to take some time and play around with Qt Designer in order to easily understand the relations between different widget types and how they are managed in layouts.