文章目录
1.垂直布局和水平布局
在PyQt5中,垂直布局(QVBoxLayout)和水平布局(QHBoxLayout)是常用的布局管理器,用于在GUI应用程序中组织和布置窗口部件。它们分别沿着垂直和水平方向排列窗口部件,使得窗口中的部件能够按照指定的方向排列。
垂直布局(QVBoxLayout):
- 简介:垂直布局会将窗口部件垂直排列,从上到下依次排列。通常用于实现垂直方向上的布局需求。
- 使用方法:可以通过
QVBoxLayout()
创建一个垂直布局对象,然后使用addWidget()
方法添加窗口部件,最后使用setLayout()
方法将该布局设置为窗口的布局。
水平布局(QHBoxLayout):
- 简介:水平布局会将窗口部件水平排列,从左到右依次排列。通常用于实现水平方向上的布局需求。
- 使用方法:可以通过
QHBoxLayout()
创建一个水平布局对象,然后使用addWidget()
方法添加窗口部件,最后使用setLayout()
方法将该布局设置为窗口的布局。
import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout, QHBoxLayout, QApplication
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 创建两个按钮
button1 = QPushButton('Button 1', self)
button2 = QPushButton('Button 2', self)
button3 = QPushButton('Button 3', self)
# 创建垂直布局
vbox = QVBoxLayout()
vbox.addWidget(button1) # 将按钮1添加到垂直布局中
vbox.addWidget(button2) # 将按钮2添加到垂直布局中
# 创建水平布局
hbox = QHBoxLayout()
hbox.addWidget(button3) # 将按钮3添加到水平布局中
hbox.addLayout(vbox) # 将垂直布局添加到水平布局中
# 将水平布局设置为窗口的布局
self.setLayout(hbox)
self.setWindowTitle('Layout Example')
self.setGeometry(300, 300, 300, 150)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
运行上面代码,我们可以得到如下窗口,其中Button1和Button2是垂直布局,然后Button3和垂直布局(Button1和Button2)又形成水平布局。
2. 布局中的addStrech
addStretch
方法是布局管理器中的一个函数,用于向布局中添加一个伸缩项。伸缩项是一种特殊的空白部件,它可以利用额外的空间来调整布局中其他部件的大小和位置。通常用于调整部件之间的间距或者在布局中创建弹性空间。参数 stretch
指定了伸缩项的弹性系数,用于指定伸缩项在布局中所占的比例。如果有多个伸缩项,它们的弹性系数决定了它们之间的拉伸比例。 (这句话可以通过2.3部分的例子进行理解)
2.1 我们首先看只有一个Strech的情况,比较容易理解
import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout, QApplication
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 创建两个按钮
button1 = QPushButton('Button 1', self)
button2 = QPushButton('Button 2', self)
# 创建垂直布局
vbox = QVBoxLayout()
vbox.addWidget(button1) # 将按钮1添加到垂直布局中
vbox.addStretch(1) # 添加一个伸缩项
vbox.addWidget(button2) # 将按钮2添加到垂直布局中
# 将垂直布局设置为窗口的布局
self.setLayout(vbox)
self.setWindowTitle('Stretch Example')
self.setGeometry(300, 300, 300, 150)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
运行结果如下,在这个示例中,我们创建了两个按钮,并使用垂直布局将它们排列在窗口中。在按钮2之前添加了一个伸缩项,这个伸缩项会占据额外的空间,使得按钮2能够被放置在窗口的底部。因为伸缩项的弹性系数为1,所以它会尽可能地拉伸以填充空白空间。
2.2 两个Strech
现在,我们在button1前也加一个Strech, 代码如下(只显示改变部分,其它部分代码不变)
# 创建垂直布局
vbox = QVBoxLayout()
vbox.addStretch(1) # 添加一个伸缩项
vbox.addWidget(button1) # 将按钮1添加到垂直布局中
vbox.addStretch(1) # 添加一个伸缩项
vbox.addWidget(button2) # 将按钮2添加到垂直布局中
运行结果如下,可以看到,button1和button2外的空白部分被这两个Strech等分了
2.3 多个Strech
现在,我们在button2后也加一个Strech, 代码如下(只显示改变部分,其它部分代码不变)
# 创建垂直布局
vbox = QVBoxLayout()
vbox.addStretch(1) # 添加一个伸缩项
vbox.addWidget(button1) # 将按钮1添加到垂直布局中
vbox.addStretch(1) # 添加一个伸缩项
vbox.addWidget(button2) # 将按钮2添加到垂直布局中
vbox.addStretch(1) # 添加一个伸缩项
运行结果如下,可以看到,button1和button2外的空白部分被这三个Strech等分了
接下来,我们把button2后的Strech参数改为3,看看效果,代码如下(只显示改变部分,其它部分代码不变)
# 创建垂直布局
vbox = QVBoxLayout()
vbox.addStretch(1) # 添加一个伸缩项
vbox.addWidget(button1) # 将按钮1添加到垂直布局中
vbox.addStretch(1) # 添加一个伸缩项
vbox.addWidget(button2) # 将按钮2添加到垂直布局中
vbox.addStretch(3) # 添加一个伸缩项
运行结果如下,可以看到,button1和button2外的空白部分被分成五份,第一个Strech和第二个Strech各占一份,第三个Strech占三份。用这个例子再去理解上面标注黄色的部分就不难理解了。
3.栅格布局
栅格布局(QGridLayout)是 PyQt5 中常用的布局管理器之一,它将窗口部件按照网格的形式排列,可以实现比较复杂的界面布局。栅格布局将窗口分成行和列,每个窗口部件都可以占据一个或多个网格。
使用方法:
- 创建 QGridLayout 对象:使用
QGridLayout()
创建一个栅格布局对象。
grid = QGridLayout()
- 添加部件到布局:使用
addWidget()
方法将窗口部件添加到布局中,并指定其所在的行和列以及占据的行数和列数。
grid.addWidget(widget, row, column, rowSpan, columnSpan)
- 设置布局到窗口:使用
setLayout()
方法将栅格布局设置为窗口的布局。
self.setLayout(grid)
我们用下面的例子展示如何使用栅格布局:
import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QGridLayout, QApplication
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 创建三个按钮
button1 = QPushButton('Button 1', self)
button2 = QPushButton('Button 2', self)
button3 = QPushButton('Button 3', self)
# 创建栅格布局
grid = QGridLayout()
grid.addWidget(button1, 0, 0) # 将按钮1放在第0行第0列
grid.addWidget(button2, 0, 1) # 将按钮2放在第0行第1列
grid.addWidget(button3, 1, 0, 1, 2) # 将按钮3放在第1行第0列,占据1行2列
# 将栅格布局设置为窗口的布局
self.setLayout(grid)
self.setWindowTitle('Grid Layout')
self.setGeometry(300, 300, 300, 150)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
运行结果如下,在这个示例中,我们创建了三个按钮,并使用栅格布局将它们排列在窗口中。按钮1位于第0行第0列,按钮2位于第0行第1列,按钮3位于第1行第0列,并占据了第1行的两列。
4. 使用栅格布局来创建一个计算器
让我们创建一个简单的计算器应用程序,使用栅格布局来排列按钮和显示结果
import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QLineEdit, QVBoxLayout, QGridLayout, QApplication
class Calculator(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resultLineEdit = QLineEdit()
self.resultLineEdit.setReadOnly(True) # 设置为只读模式,用于显示计算结果
# 创建按钮
buttons = [
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', '=', '+',
'C' # 归零按钮
]
# 创建栅格布局
grid = QGridLayout()
for i, btn_text in enumerate(buttons):
row = i // 4
col = i % 4
button = QPushButton(btn_text)
button.clicked.connect(self.onButtonClicked) # 连接按钮的点击事件
grid.addWidget(button, row, col)
# 创建垂直布局,并添加结果显示框和栅格布局
vbox = QVBoxLayout()
vbox.addWidget(self.resultLineEdit) # 将结果显示框添加到垂直布局中
vbox.addLayout(grid) # 将栅格布局添加到垂直布局中
self.setLayout(vbox) # 将垂直布局设置为窗口的布局
self.setWindowTitle('Calculator')
self.setGeometry(300, 300, 250, 200)
def onButtonClicked(self):
sender = self.sender()
clicked_text = sender.text()
if clicked_text == '=':
try:
result = str(eval(self.resultLineEdit.text())) # 计算结果
self.resultLineEdit.setText(result) # 在结果显示框中显示结果
except Exception as e:
self.resultLineEdit.setText('Error') # 如果出现错误,则显示错误消息
elif clicked_text == 'C': # 点击归零按钮
self.resultLineEdit.setText('') # 清空结果显示框
else:
current_text = self.resultLineEdit.text() # 获取当前结果显示框中的文本
new_text = current_text + clicked_text # 将点击的按钮文本添加到当前文本后面
self.resultLineEdit.setText(new_text) # 在结果显示框中显示新文本
if __name__ == '__main__':
app = QApplication(sys.argv)
calc = Calculator()
calc.show()
sys.exit(app.exec_())
运行结果如下