如何在 PyQt5(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)
        grid.addWidget(self.but9,1,2)
        grid.addWidget(self.but8,1)
        grid.addWidget(self.but7,0)
        grid.addWidget(self.but6,2,2)
        grid.addWidget(self.but5,1)
        grid.addWidget(self.but4,0)
        grid.addWidget(self.but3,3,2)
        grid.addWidget(self.but2,1)
        grid.addWidget(self.but1,0)
        grid.addWidget(self.but0,4,0)

        # buttons for operation
        self.but_devide.setStyleSheet('background: #7FFFD4')
        grid.addWidget(self.but_devide,4)
        self.but_multiply.setStyleSheet('background: #7FFFD4')
        grid.addWidget(self.but_multiply,4)
        self.but_add.setStyleSheet('background: #7FFFD4')
        grid.addWidget(self.but_add,4)
        self.but_decreas.setStyleSheet('background: #7FFFD4')
        grid.addWidget(self.but_decreas,4)
        self.but_equal.setStyleSheet('background: #008B8B')
        grid.addWidget(self.but_equal,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

解决方法

tl;博士

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

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

说明

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

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

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

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

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

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

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

    grid.addWidget(self.resultText,5)

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

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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...