Home > Back-end >  How can I keep row and column size the same with the grid layout in PyQt5?
How can I keep row and column size the same with the grid layout in PyQt5?

Time:09-29

I'm trying to create a GUI for a chess game. I'm using the grid layout and when the main window opens, the labels I have are in the correct size. However, when I resize the window, the grid layout does move along with the window but its contents are out of alignment and the row and column sizes don't match anymore. Is there a way of making it so the cell sizes in the grid layout will always be a square (so row size = column size).

Correct Scale where rowsize = columnsize : Correct Scale where rowsize = columnsize

Incorrect Scales example where rowsize is not equal to columnsize : Incorrect Scales example

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setGeometry(500,150,860,860)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        #Adding Grid Layout to the main widget
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.gridLayout.setHorizontalSpacing(0)
        self.gridLayout.setVerticalSpacing(0)
        
        all_position_labels = []
        
        colour = False
        for x in range(8):
            row = []
            
            for y in range(8):
                #Creating the labels
                self.position = QtWidgets.QLabel(self.centralwidget)
                self.position.setText("Place "   str(x)   " "   str(y))
                if colour == True:
                    self.position.setStyleSheet("border: 0.1em solid black; background: gray;")
                    colour = False
                else:
                    self.position.setStyleSheet("border: 0.1em solid black;")
                    colour = True
                #Adding labels to the GridLayout                
                self.gridLayout.addWidget(self.position, x, y, 1, 1)
                

                row.append(self.position)
            all_position_labels.append(row)   

            if colour == True:
                colour = False
            else:
                colour = True
        del row
        

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 20))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Thanks.

CodePudding user response:

The size of the labels depends on the size of the container so a possible solution is to resize the widget based on the size of the window.

from PyQt5.QtCore import QSize, Qt
from PyQt5.QtWidgets import (
    QApplication,
    QGridLayout,
    QLabel,
    QMainWindow,
    QStyle,
    QWidget,
)


class CentralWidget(QWidget):
    def __init__(self, widget):
        super().__init__()
        self._widget = widget
        self.widget.setParent(self)

    @property
    def widget(self):
        return self._widget

    def resizeEvent(self, event):
        super().resizeEvent(event)
        size = min(self.width(), self.height())
        r = QStyle.alignedRect(
            Qt.LeftToRight, Qt.AlignCenter, QSize(size, size), self.rect()
        )
        self.widget.setGeometry(r)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        container = QWidget()
        central_widget = CentralWidget(container)
        self.setCentralWidget(central_widget)

        lay = QGridLayout(container)
        lay.setSpacing(0)
        lay.setContentsMargins(0, 0, 0, 0)
        colour = False
        for i in range(8):
            for j in range(8):
                label = QLabel(f"Place {i} {j}", alignment=Qt.AlignCenter)
                label.setStyleSheet(
                    "border: 0.1em solid black;"
                    if colour
                    else "border: 0.1em solid black; background: gray;"
                )
                lay.addWidget(label, i, j)
                colour = not colour
            colour = not colour


def main():
    app = QApplication([])
    app.setStyle("fusion")
    view = MainWindow()
    view.resize(860, 860)
    view.show()
    app.exec_()


if __name__ == "__main__":
    main()
  • Related