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

时间:2021-04-30 11:10:53

标签: python layout pyqt5 widget qgridlayout

我有问题。我开始学习 PyQt5,我想做一个计算器。所以我学会了如何热情 我的 Widget 带有 QGridLayout,但我无法更改 Widget 的大小。有些小部件比其他小部件大,我不明白。我尝试了不同的方法,如(调整大小、设置几何),但没有奏效。我也想调整 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()

Here is how my widgets look like

1 个答案:

答案 0 :(得分:1)

tl;博士

在向网格布局添加小部件时选择合适的列跨度

    grid.addWidget(self.resultText, 0, 0, 1, 5)

说明

布局管理器的重点在于它管理布局

基于设置它的小部件及其管理的所有项目(小部件甚至其他嵌套布局),考虑所有约束(可能的最小/最大尺寸),提示(首选尺寸)和大小策略(是否以及如何调整小部件的大小),然后它决定应将这些项目放置在哪里以及它们有多大。

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

大多数小部件会根据他们的 sizeHint 建议尝试占用布局提供的尽可能多的空间,如果有更多可用空间,他们可能会尝试使用它。按钮的宽度是这种情况,但它们的高度(通常是固定的)则不然。

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

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

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

    grid.addWidget(self.resultText, 0, 0, 1, 5)

其中说:在第 0 行和第 0 列上添加小部件,并使其仅占据一行而五列。
如果未给出 span 参数,则它们隐式地仅占用一行和一列。请注意,即使您只对一个跨度“方向”感兴趣,两个 跨度参数都是必需的(它们不是关键字参数)。

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