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
相关产品推荐
相关产品推荐

