问题描述
我有问题。我开始学习 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()
解决方法
tl;博士
在向网格布局添加小部件时选择合适的列跨度:
grid.addWidget(self.resultText,1,5)
说明
布局管理器的重点在于它管理布局。
基于设置它的小部件及其管理的所有项目(小部件甚至其他嵌套布局),考虑所有约束(可能的最小/最大尺寸),提示(首选尺寸)和大小策略(是否以及如何调整小部件的大小),然后它决定应将这些项目放置在哪里以及它们有多大。
考虑到所有这些,您可以理解尝试手动调整这些小部件的大小没有意义,因为布局会尽快覆盖它[1]。
大多数小部件会根据他们的 sizeHint 建议尝试占用布局提供的尽可能多的空间,如果有更多可用空间,他们可能会尝试使用它。按钮的宽度是这种情况,但它们的高度(通常是固定的)则不然。
当窗口被映射(第一次显示)时,布局会考虑以上所有内容,包括大小提示,并尝试使用允许所有这些提示得到尊重的大小.事实上,如果您尝试将窗口大小调整为尽可能小的尺寸,您会看到所有按钮(和行编辑)很可能会获得相同的大小。
您正在使用网格布局,它允许将项目放在网格的单元格内:行和列。由于您将 QLineEdit 放在第一列中,并且该小部件的默认大小提示比按钮宽,因此结果是当第一次显示窗口时,第一列将使用该宽度,并且由于按钮将其宽度调整为可用空间,第一列中的那些将显示为与行编辑一样宽。
网格布局允许使用 spanning(请参阅 documentation,这是一种让项目占据多个单元格行和/或列的方法。考虑到您的程序的目的,如果该行编辑占据整个水平空间,它可能看起来会更好,并且由于您使用了 5 列(操作按钮位于第 4 列,索引始终从 0 开始),这就是我们如何得到上面的行:
grid.addWidget(self.resultText,5)
其中说:在第 0 行和第 0 列上添加小部件,并使其仅占据一行而五列。
如果未给出 span 参数,则它们隐式地仅占用一行和一列。请注意,即使您只对一个跨度“方向”感兴趣,两个 跨度参数都是必需的(它们不是关键字参数)。
[1] 可以使用 resize
或 setGeometry
,在布局完成后工作;但是尝试这样做没有什么意义:只要以任何方式(从用户或系统)调整窗口大小,布局就会覆盖这些手动尝试。如果您尝试在显示窗口之前 这样做,就会发生这种情况:当小部件第一次显示时,它还会收到一个 resize 事件,如果该小部件有一个布局,它会自动通知该布局,以便它可以执行所有计算。