【Python篇】PyQt5 超详细教程——由入门到精通
在上一部分的 PyQt5 教程中,我们学习了如何安装 PyQt5,如何创建简单的窗口,并初步了解了事件处理。在本篇教程中,我们将进一步深入,探讨 PyQt5 中的布局管理、信号与槽机制、常用控件(如按钮、文本框、标签等)的使用,并通过一些代码示例来加深理解。
PyQt5 是一个功能强大且易于扩展的 GUI 库,适用于需要创建桌面应用程序的 Python 开发者。本篇教程将带你从基础逐步深入,帮助你掌握更多实用技巧。
一、布局管理(Layout Management)
布局管理器决定了控件在窗口中的排列方式。PyQt5 提供了多种布局管理器,最常用的是水平布局 (QHBoxLayout
)、垂直布局 (QVBoxLayout
) 和网格布局 (QGridLayout
)。接下来,我们将通过几个示例来展示这些布局管理器的使用。
1.1 水平布局 (QHBoxLayout
)
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout()
btn1 = QPushButton('Button 1', self)
btn2 = QPushButton('Button 2', self)
btn3 = QPushButton('Button 3', self)
hbox.addWidget(btn1)
hbox.addWidget(btn2)
hbox.addWidget(btn3)
self.setLayout(hbox)
self.setWindowTitle('QHBoxLayout Example')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
在这个示例中,我们创建了一个水平布局,包含三个按钮。布局管理器自动将按钮水平排列,并根据窗口大小自动调整它们的尺寸。
1.2 垂直布局 (QVBoxLayout
)
垂直布局与水平布局类似,只不过控件是垂直排列的。代码示例如下:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
vbox = QVBoxLayout()
btn1 = QPushButton('Button 1', self)
btn2 = QPushButton('Button 2', self)
btn3 = QPushButton('Button 3', self)
vbox.addWidget(btn1)
vbox.addWidget(btn2)
vbox.addWidget(btn3)
self.setLayout(vbox)
self.setWindowTitle('QVBoxLayout Example')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
1.3 网格布局 (QGridLayout
)
网格布局允许你将控件放置在一个二维的网格中。下面是一个使用网格布局的示例:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QGridLayout
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
grid = QGridLayout()
btn1 = QPushButton('Button 1', self)
btn2 = QPushButton('Button 2', self)
btn3 = QPushButton('Button 3', self)
btn4 = QPushButton('Button 4', self)
grid.addWidget(btn1, 0, 0)
grid.addWidget(btn2, 0, 1)
grid.addWidget(btn3, 1, 0)
grid.addWidget(btn4, 1, 1)
self.setLayout(grid)
self.setWindowTitle('QGridLayout Example')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
在这个示例中,四个按钮被放置在一个 2×2 的网格中,每个按钮占据一个单元格。你可以通过调整 addWidget()
方法中的参数来指定控件的行和列。
二、信号与槽机制(Signals and Slots)
PyQt5 中的信号与槽机制是实现控件之间通信的关键。信号表示事件的发生,而槽是处理该事件的方法。控件在某些情况下会发出信号,比如用户点击按钮、选择菜单项等。
2.1 基本信号与槽连接
下面是一个简单的信号与槽的例子:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
vbox = QVBoxLayout()
self.btn = QPushButton('Click me', self)
self.btn.clicked.connect(self.on_click)
vbox.addWidget(self.btn)
self.setLayout(vbox)
self.setWindowTitle('Signal and Slot Example')
self.show()
def on_click(self):
self.btn.setText('Clicked!')
print('Button was clicked')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
在这个示例中,我们将按钮的 clicked
信号连接到 on_click
槽。当按钮被点击时,会调用 on_click
方法,并更改按钮的文本。
2.2 自定义信号与槽
除了使用 PyQt5 提供的内置信号外,你还可以创建自定义信号与槽。下面是一个创建自定义信号的示例:
from PyQt5.QtCore import pyqtSignal, QObject
class Communicate(QObject):
custom_signal = pyqtSignal()
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.c = Communicate()
self.c.custom_signal.connect(self.on_custom_signal)
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('Custom Signal Example')
self.show()
# Emit custom signal after 2 seconds
QTimer.singleShot(2000, self.emit_signal)
def emit_signal(self):
self.c.custom_signal.emit()
def on_custom_signal(self):
print('Custom signal received!')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
在这个示例中,我们定义了一个名为 custom_signal
的自定义信号,并在 2 秒后发出该信号。
三、常用控件的使用
3.1 按钮(QPushButton)
按钮是最常见的控件之一,PyQt5 中的按钮可以通过 QPushButton
类来创建。我们之前已经展示了如何使用按钮以及如何响应按钮的点击事件。
3.2 标签(QLabel)
标签是显示文本或图像的控件。QLabel
类可以用来创建标签,下面是一个简单的标签示例:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
vbox = QVBoxLayout()
label1 = QLabel('This is a label', self)
label2 = QLabel('<b>This is a bold label</b>', self)
vbox.addWidget(label1)
vbox.addWidget(label2)
self.setLayout(vbox)
self.setWindowTitle('QLabel Example')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
3.3 文本输入框(QLineEdit)
QLineEdit
是一个单行文本输入框,允许用户输入文本。下面是一个简单的示例,展示了如何获取用户输入的文本:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QVBoxLayout, QPushButton
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
vbox = QVBoxLayout()
self.line_edit = QLineEdit(self)
btn = QPushButton('Submit', self)
btn.clicked.connect(self.on_click)
vbox.addWidget(self.line_edit)
vbox.addWidget(btn)
self.setLayout(vbox)
self.setWindowTitle('QLineEdit Example')
self.show()
def on_click(self):
text = self.line_edit.text()
print(f'Input text: {text}')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
3.4 复选框(QCheckBox)
复选框可以用来让用户选择多个选项。QCheckBox
类可以用来创建复选框,下面是一个简单的示例:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QCheckBox
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
vbox = QVBoxLayout()
self.cb1 = QCheckBox('Option 1', self)
self.cb2 = QCheckBox('Option 2', self)
vbox.addWidget(self.cb1)
vbox.addWidget(self.cb2)
self.setLayout(vbox)
self.setWindowTitle('QCheckBox Example')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
四、总结
在本篇教程中,我们深入学习了 PyQt5 中的布局管理器、信号与槽机制以及一些常用控件的使用。通过丰富的代码示例,展示了如何创建和管理 GUI 界面。在下一部分教程中,我们将继续探讨更多高级主题,包括自定义控件、事件过滤和绘图等内容。
PyQt5 的灵活性和强大的功能使其成为开发桌面应用程序的理想选择,掌握了这些基础内容后,你将能够轻松构建功能丰富的应用程序。
作者:一只蜗牛儿