Search code examples
pythonlayoutpyqtpyqt5qgridlayout

PyQt5 : layout buttons with equal column width


I was using PyQt5 to create a grid layout for my username, password label and input fields and for my submit and cancel button.

I added equal row width of 1 for all my widgets, however for my cancel and submit button and I want them to be of the same cell width.

This is what I tried

from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
import sys

class MainWindow(qtw.QWidget):
    
    def __init__(self, *arg, **kwargs):
        super().__init__(*arg, **kwargs)
        # custom code goes here
        username_label = qtw.QLabel('Username')
        password_label = qtw.QLabel('Password')

        username_input = qtw.QLineEdit()
        password_input = qtw.QLineEdit(echoMode = qtw.QLineEdit.Password)

        cancel_button = qtw.QPushButton('Cancel')
        submit_button = qtw.QPushButton('Login')
        
        layout = qtw.QGridLayout()
        layout.addWidget(username_label,0, 0, 1, 2) # 0,0 cell, rowspan : 1, colSpan : 2
        layout.addWidget(username_input, 0, 1, 1, 3) # 0, 1 cell
        layout.addWidget(password_label, 1, 0, 1, 2) # 1, 0 cell
        layout.addWidget(password_input, 1, 1, 1, 3) # 1, 1 cell
        layout.addWidget(cancel_button, 2, 0, 1)
        layout.addWidget(submit_button, 2, 1, 1)

        self.setLayout(layout)
        self.show()

if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)
    w = MainWindow()
    sys.exit(app.exec_())

However this gives me

enter image description here

Where as I expected, cancel and login to have equal width.

enter image description here


Solution

  • You need to create a separate layout for the buttons, so they can resize independently of the other widgets. Also, the problem with overlapping widgets can be fixed by using the default row/column spans. I have also added a stretchable spacer so the buttons stay at the bottom when resizing the window.

        cancel_button = qtw.QPushButton('Cancel')
        submit_button = qtw.QPushButton('Login')
    
        hbox = qtw.QHBoxLayout()
        hbox.addWidget(cancel_button)
        hbox.addWidget(submit_button)
    
        layout = qtw.QGridLayout()
        layout.addWidget(username_label,0, 0)
        layout.addWidget(username_input, 0, 1)
        layout.addWidget(password_label, 1, 0)
        layout.addWidget(password_input, 1, 1)
        layout.setRowStretch(2, 1)
        layout.addLayout(hbox, 3, 0, 1, 2)
    
        self.setLayout(layout)
    

    Default:

    enter image description here

    Resized:

    enter image description here