Python 如何在PyQt5(QGridLayout)中调整小部件的大小

Python 如何在PyQt5(QGridLayout)中调整小部件的大小,python,layout,pyqt5,widget,qgridlayout,Python,Layout,Pyqt5,Widget,Qgridlayout,我有个问题。我开始学习PyQt5,我想做一个计算器。所以我学会了如何充满激情 我的小部件具有QGridLayout,但我无法更改小部件的大小。有些小部件比其他小部件大,我不理解这一点。我尝试了不同的方法,比如(调整大小、设置几何体),但没有成功。我还想调整QLineEdit变量的大小,但我不能。以下是我的问题代码和图片: import PyQt5.QtWidgets as qwd import PyQt5.QtGui as qtg class CreateWindow(qwd.QWidget)

我有个问题。我开始学习PyQt5,我想做一个计算器。所以我学会了如何充满激情 我的小部件具有QGridLayout,但我无法更改小部件的大小。有些小部件比其他小部件大,我不理解这一点。我尝试了不同的方法,比如(调整大小、设置几何体),但没有成功。我还想调整QLineEdit变量的大小,但我不能。以下是我的问题代码和图片:

import PyQt5.QtWidgets as qwd
import PyQt5.QtGui as qtg

class CreateWindow(qwd.QWidget):
    # create window
    def __init__(self):
        super().__init__()
        
        self.setWindowTitle('calculator')
        self.setWindowIcon(qtg.QIcon('calculator.png'))
        self.setStyleSheet('background: #FAEBD7;')
        # self.setFixedWidth(300)
        # self.setFixedHeight(170)

        # show result
        self.text = '0'

        self.UIcomponents()

        self.show()

    def UIcomponents(self):
        # layout

        grid = qwd.QGridLayout()
        

        # show numbers
        self.resultText = qwd.QLineEdit(self.text)
        self.resultText.setReadOnly(True)
        self.resultText.setStyleSheet('background: #FFFAFA;')

        # buttons
        self.but9 = qwd.QPushButton('9')
        self.but8 = qwd.QPushButton('8')
        self.but7 = qwd.QPushButton('7')
        self.but6 = qwd.QPushButton('6')
        self.but5 = qwd.QPushButton('5')
        self.but4 = qwd.QPushButton('4')
        self.but3 = qwd.QPushButton('3')
        self.but2 = qwd.QPushButton('2')
        self.but1 = qwd.QPushButton('1')
        self.but0 = qwd.QPushButton('0')
        self.but_add = qwd.QPushButton('+')
        self.but_decreas = qwd.QPushButton('-')
        self.but_multiply = qwd.QPushButton('*')
        self.but_devide = qwd.QPushButton('/')     
        self.but_equal = qwd.QPushButton('=')

        # positionate the buttons
        grid.addWidget(self.resultText, 0, 0)
        grid.addWidget(self.but9, 1, 2)
        grid.addWidget(self.but8, 1, 1)
        grid.addWidget(self.but7, 1, 0)
        grid.addWidget(self.but6, 2, 2)
        grid.addWidget(self.but5, 2, 1)
        grid.addWidget(self.but4, 2, 0)
        grid.addWidget(self.but3, 3, 2)
        grid.addWidget(self.but2, 3, 1)
        grid.addWidget(self.but1, 3, 0)
        grid.addWidget(self.but0, 4, 0)

        # buttons for operation
        self.but_devide.setStyleSheet('background: #7FFFD4')
        grid.addWidget(self.but_devide, 1, 4)
        self.but_multiply.setStyleSheet('background: #7FFFD4')
        grid.addWidget(self.but_multiply, 2, 4)
        self.but_add.setStyleSheet('background: #7FFFD4')
        grid.addWidget(self.but_add, 3, 4)
        self.but_decreas.setStyleSheet('background: #7FFFD4')
        grid.addWidget(self.but_decreas, 4, 4)
        self.but_equal.setStyleSheet('background: #008B8B')
        grid.addWidget(self.but_equal, 4, 2)

        # connect buttons
        self.but9.clicked.connect(lambda state, number = '9': self.show_result(number))
        self.but8.clicked.connect(lambda state, number = '8': self.show_result(number))
        self.but7.clicked.connect(lambda state, number = '7': self.show_result(number))
        self.but6.clicked.connect(lambda state, number = '6': self.show_result(number))
        self.but5.clicked.connect(lambda state, number = '5': self.show_result(number))
        self.but4.clicked.connect(lambda state, number = '4': self.show_result(number))
        self.but3.clicked.connect(lambda state, number = '3': self.show_result(number))
        self.but2.clicked.connect(lambda state, number = '2': self.show_result(number))
        self.but1.clicked.connect(lambda state, number = '1': self.show_result(number))
        self.but0.clicked.connect(lambda state, number = '0': self.show_result(number))
        self.but_decreas.clicked.connect(lambda state, oper = '-': self.chose_oper(oper))
        self.but_add.clicked.connect(lambda state, oper = '+': self.chose_oper(oper))
        self.but_multiply.clicked.connect(lambda state, oper = '*': self.chose_oper(oper))
        self.but_devide.clicked.connect(lambda state, oper = '/': self.chose_oper(oper))

        self.setLayout(grid)

    def show_result(self, number):
        if len(self.text) != 20:
            print(len(self.text))
            if self.text[0] == '0':
                self.text = ''
            self.text += number
            self.resultText.setText(str(self.text))
            
    def chose_oper(self, oper):
        if self.text[0] != '0':
                self.text += oper
        self.resultText.setText(str(self.text))

def create_app():
    app = qwd.QApplication([])
    wind = CreateWindow()
    # set app style
    app.setStyle('Fusion')

    app.exec_()

create_app()

tl;博士 将小部件添加到网格布局时,请选择适当的列跨度:

    grid.addWidget(self.resultText, 0, 0, 1, 5)
解释 布局管理器的要点是管理布局

基于设置它的小部件和它管理的所有项目(小部件或其他嵌套布局),考虑所有约束(可能的最小/最大大小)、提示(首选大小)和大小策略(如果以及如何调整小部件的大小),然后它决定这些项目应该放置在何处以及它们的大小

考虑到所有这些,您可以理解手动调整这些小部件的大小是没有意义的,因为布局会尽快覆盖它[1]

根据他们的建议,大多数小部件都会尽量占用布局给他们的空间,如果有更多的空间,他们可能会尝试使用它。按钮的宽度就是这样,但其高度(通常是固定的)不是这样

当一个窗口被映射(第一次显示)时,布局会考虑以上所有因素,包括大小提示,并尝试使用一个允许所有这些提示都得到遵守的大小。事实上,如果您尝试将窗口的大小调整为可能的小尺寸,您将看到所有按钮(以及行编辑)很可能都具有相同的大小

您使用的是网格布局,它允许在网格的单元格中放置项目:行和列。由于将QLineEdit放在第一列中,并且该小部件的默认大小提示比按钮宽,因此,当第一次显示窗口时,第一列将使用该宽度,并且由于按钮根据可用空间调整其宽度,因此第一列中的按钮将显示为与行编辑一样宽

网格布局允许使用跨距(请参阅,这是一种让项目占用多个单元格行和/或列的方法。考虑到程序的用途,如果该行编辑占用整个水平空间,并且由于您使用的是5列(操作按钮位于第4列,索引始终从0开始),则该行编辑可能会看起来更好我们就是这样得到上面这句话的:

    grid.addWidget(self.resultText, 0, 0, 1, 5)
上面写着:在第0行和第0列添加小部件,使其只占用一行,但占用五列。
如果未提供span参数,则它们仅隐式占用一行和一列。请注意,即使您只对一个span“方向”感兴趣,也需要两个span参数(它们不是关键字参数)

[1] 布局完成工作后,可以使用
调整大小
设置几何图形
;但尝试这样做没有什么意义:只要以任何方式(从用户或系统)调整窗口大小,布局将覆盖手动尝试。如果您在显示窗口之前尝试这样做,则会发生这种情况:当小部件第一次显示时,它也会收到一个调整大小事件,如果该小部件有一个布局,它会自动通知该布局,以便它可以执行所有计算