如何在 PyQt5 中保持行和列大小与网格布局相同?

Posted

技术标签:

【中文标题】如何在 PyQt5 中保持行和列大小与网格布局相同?【英文标题】:How can I keep row and column size the same with the grid layout in PyQt5? 【发布时间】:2021-11-20 22:20:38 【问题描述】:

我正在尝试为国际象棋游戏创建 GUI。我正在使用网格布局,当主窗口打开时,我拥有的标签大小正确。但是,当我调整窗口大小时,网格布局确实会随着窗口移动,但其内容不对齐,并且行和列大小不再匹配。有没有办法让网格布局中的单元格大小始终是正方形(所以行大小=列大小)。

行大小 = 列大小的正确比例:

不正确的比例示例,其中行大小不等于列大小:

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_())

谢谢。

【问题讨论】:

【参考方案1】:

标签的大小取决于容器的大小,因此可能的解决方案是根据窗口大小调整小部件的大小。

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

【讨论】:

以上是关于如何在 PyQt5 中保持行和列大小与网格布局相同?的主要内容,如果未能解决你的问题,请参考以下文章

如何创建可重用的 WPF 网格布局

你真的了解Grid布局吗?

异构网格布局

我们如何在 ext js 4.2 中突出显示网格面板的行和列?

Swing 布局 - 在保持组件尺寸的同时使用网格

如何通过单击pyqt5中的按钮来制作qlineedit的动态行和列?