3、PyQt5 基础与第一个窗口
好,咱们正式开始动手了。
上一章我们把开发环境搭好了,Python 能跑,PyQt5 也装上了。现在,是时候写第一个窗口了。
说实话,我当年第一次接触 PyQt5 时,看着那一堆类和方法,心里也犯嘀咕。但后来发现,核心概念就那么几个。搞懂了,后面就顺了。
3.1 PyQt5 核心概念:信号与槽、事件循环
先聊两个最基础的概念。不理解它们,后面写代码会懵。
3.1.1 信号与槽
说白了,这就是 PyQt5 里对象之间通信的方式。
你想想看,你点了一个按钮,程序怎么知道该执行哪段代码?
在 PyQt5 里,按钮被点击时会发射一个信号(Signal)。你需要把这个信号连接到一个槽(Slot)上。槽,就是一个函数。信号发射了,槽函数就会被自动调用。
核心理解:
- 信号(Signal):事件发生时发出的通知。比如按钮被点击、滑块被拖动、窗口被关闭。
- 槽(Slot):响应信号的函数。可以是 PyQt5 内置的,也可以是你自己写的。
- 连接(Connect):把信号和槽绑定在一起。
我在项目中遇到过一个问题:多个按钮需要执行类似的操作。如果每个按钮都写一个槽函数,代码会非常冗余。后来我学会了用同一个槽函数,通过 sender() 方法判断是哪个按钮触发的。嗯,这个技巧后面会讲。
# 最简单的信号与槽示例
button.clicked.connect(self.on_button_clicked)
def on_button_clicked(self):
print("按钮被点击了!")
3.1.2 事件循环
这个更关键。
你写一个普通的 Python 脚本,跑完就结束了。但 GUI 程序不能这样。它得一直等着,等用户点击、等键盘输入、等窗口重绘。
事件循环(Event Loop)就是干这个的。它像一个永不停止的 while 循环,不断监听各种事件,然后分发给对应的处理函数。
我的理解:
事件循环就是 GUI 程序的心脏。它一直在跳,程序才能活着。你调用 app.exec_() 时,事件循环就启动了。程序会一直运行,直到你关闭窗口。
为什么会这样?因为 PyQt5 把底层的消息循环封装好了。你不需要自己写 while 循环,只需要调用 app.exec_() 就行。
3.2 创建第一个主窗口(QMainWindow)
好,概念讲完了。咱们写代码。
我个人习惯,每次新建项目都会先创建一个主窗口。QMainWindow 是 PyQt5 里最常用的窗口类。它自带菜单栏、工具栏、状态栏,非常方便。
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 设置窗口标题
self.setWindowTitle("我的第一个地面站")
# 设置窗口图标(需要先导入 QIcon)
# self.setWindowIcon(QIcon('icon.png'))
# 设置窗口大小
self.resize(800, 600)
# 设置窗口位置(屏幕左上角为原点)
self.move(300, 200)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
这段代码,你直接复制到 Python 文件里运行,就能看到一个窗口了。
注意:
如果你用的是 PyQt5 的某些版本,设置图标时可能会遇到路径问题。我曾经因为图标路径写错了,折腾了半小时。建议先用注释掉图标设置,等窗口跑起来再慢慢调。
3.3 设置窗口标题、图标、大小与位置
上面代码里已经用到了几个方法。我再详细说说。
| 方法 | 作用 | 示例 |
|---|---|---|
| setWindowTitle() | 设置窗口标题 | setWindowTitle("无人机地面站") |
| setWindowIcon() | 设置窗口图标 | setWindowIcon(QIcon('logo.png')) |
| resize() | 设置窗口大小(宽,高) | resize(1024, 768) |
| move() | 设置窗口位置(x, y) | move(100, 100) |
| setGeometry() | 同时设置位置和大小 | setGeometry(100, 100, 1024, 768) |
我个人习惯用 setGeometry(),一行代码搞定位置和大小。但要注意,它的参数顺序是 (x, y, width, height),别搞反了。
3.4 理解 QApplication 与 QWidget 的关系
这是很多人容易混淆的地方。
QApplication 是整个应用程序的管理者。它负责初始化、事件循环、全局设置。每个 PyQt5 程序有且只有一个 QApplication 实例。
QWidget 是所有窗口和控件的基类。QMainWindow 继承自 QWidget。你看到的按钮、标签、输入框,都是 QWidget 的子类。
关系总结:
- QApplication 是「老板」,管理整个程序的生命周期。
- QWidget 是「员工」,负责具体的界面展示和交互。
- 一个 QApplication 可以管理多个 QWidget。
你想想看,如果没有 QApplication,你的窗口就没人管。事件循环跑不起来,窗口显示一下就退出了。
我曾经犯过一个低级错误:在创建 QApplication 之前就创建了窗口。结果程序直接崩溃。嗯,顺序很重要。
3.5 本章知识体系
下面这张图,是我画的核心逻辑。你看一眼,应该就能把本章内容串起来。
我的建议:
刚开始学,不要纠结于所有细节。先把 QApplication 和 QMainWindow 的关系搞清楚。能跑起来一个窗口,你就成功了一半。
后面的章节,我们会在这个窗口里添加各种控件。到时候,信号与槽会频繁用到。现在有个印象就行。
好了,这一章的内容就这些。代码不多,但概念很重要。你最好亲手敲一遍,跑起来看看效果。
可可精品资料库