You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5使用Grid Layout网格布局时如何让单元格始终为正方形(行列尺寸一致)

要实现网格布局单元格始终保持正方形,你可以通过自定义控件强制宽高1:1+统一布局拉伸规则实现,具体改动如下:

实现步骤

1. 自定义正方形QLabel控件

重写QLabel的内置方法,让控件高度始终等于宽度:

class SquareLabel(QtWidgets.QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        # 开启尺寸策略为优先保证宽高比
        self.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred))

    def heightForWidth(self, width):
        # 高度等于宽度,保证正方形
        return width

    def sizeHint(self):
        # 推荐尺寸以当前宽度为基准
        return QtCore.QSize(self.width(), self.heightForWidth(self.width()))

2. 给网格布局设置行列拉伸规则

在创建网格布局后,添加以下代码,让8行8列的拉伸权重全部相等,缩放时均匀分配空间:

# 8行8列拉伸权重都设为1
for i in range(8):
    self.gridLayout.setRowStretch(i, 1)
    self.gridLayout.setColumnStretch(i, 1)

3. 替换原有QLabel为自定义SquareLabel

把你创建标签的代码里QtWidgets.QLabel替换成SquareLabel即可。

修改后完整可运行代码

from PyQt5 import QtWidgets, QtCore

class SquareLabel(QtWidgets.QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred))

    def heightForWidth(self, width):
        return width

    def sizeHint(self):
        return QtCore.QSize(self.width(), self.heightForWidth(self.width()))

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")

        # 为主组件添加Grid Layout网格布局
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.gridLayout.setHorizontalSpacing(0)
        self.gridLayout.setVerticalSpacing(0)
        
        # 设置行列拉伸权重
        for i in range(8):
            self.gridLayout.setRowStretch(i, 1)
            self.gridLayout.setColumnStretch(i, 1)
        
        all_position_labels = []
        
        colour = False
        for x in range(8):
            row = []
            
            for y in range(8):
                # 替换为自定义正方形标签
                self.position = SquareLabel(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
                # 将标签添加到Grid Layout中
                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_())

修改后无论怎么拉伸窗口,所有网格单元格都会保持1:1的正方形比例,不会出现错位问题。

内容的提问来源于stack exchange,提问作者Jack Sparrow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 11:27:03