PyQt5基础:从安装到第一个窗口程序
各位同学,今天我们来聊聊PyQt5。说实话,这个库是我做上位机开发时用得最多的工具之一。记得我第一次接触它,是在一个工业镜头测试项目里——甲方要求三天出原型,我硬是用PyQt5两天就搞定了。嗯,今天就把这些经验分享给你们。
1. PyQt5的安装
安装其实很简单,但有个坑我得先提醒你:Python版本和PyQt5版本要匹配。我曾经在Python 3.12上直接pip install PyQt5,结果报了一堆错——后来发现是版本兼容问题。
我个人习惯用Python 3.8到3.10之间的版本,稳定。安装命令就一行:
pip install PyQt5 pyqt5-tools
这里我建议加上pyqt5-tools,因为它包含了Qt Designer——我们后面会用到。装完之后,验证一下:
python -c "from PyQt5.QtWidgets import QApplication; print('OK')"
如果打印出"OK",恭喜你,环境搭好了。
--user参数就行:pip install --user PyQt5
2. Qt Designer:可视化设计利器
Qt Designer是什么?说白了,就是一个拖拽式的界面设计工具。你想想看,如果每个按钮、每个文本框都要手写代码去布局,那得多累?
启动它很简单:在命令行输入designer,或者找到安装目录下的designer.exe。界面长这样:
- 左侧是控件面板——按钮、标签、输入框都在这里
- 中间是设计区域——你的窗口画布
- 右侧是属性编辑器——调整控件的大小、颜色、文字
我在项目中常用的流程是:先用Qt Designer拖出界面,保存为.ui文件,然后用pyuic5工具转成Python代码。命令如下:
pyuic5 -x my_design.ui -o my_design.py
这样生成的代码可以直接运行。但说实话,我更喜欢另一种方式——动态加载UI文件,这样修改界面时不用重新生成代码:
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication
app = QApplication([])
window = uic.loadUi('my_design.ui')
window.show()
app.exec_()
3. 信号与槽机制:PyQt5的灵魂
信号与槽,这个词听起来有点玄乎。其实说白了就是:某个事件发生了,就触发某个函数去处理。
举个例子:你点击一个"拍照"按钮,程序就要去调用相机。这里的"点击"就是信号,"调用相机"就是槽函数。
我刚开始学的时候,总觉得这个概念抽象。直到有一次做项目,我需要让一个滑动条控制镜头的光圈值——滑动条的值变了,光圈数值显示也要跟着变。这就是典型的信号与槽:
from PyQt5.QtWidgets import QSlider, QLabel
# 创建控件
slider = QSlider()
label = QLabel('光圈值: 2.8')
# 连接信号与槽
slider.valueChanged.connect(lambda v: label.setText(f'光圈值: {v/10:.1f}'))
这里valueChanged就是信号,connect方法把信号和槽函数绑在一起。每当滑动条的值变化,标签的文字就会更新。
valueChanged信号会传递一个整数,你的槽函数就必须能接收整数参数。我曾经在这里栽过跟头——传了个字符串进去,程序直接崩溃。
PyQt5内置了很多信号,比如:
| 控件 | 信号 | 触发时机 |
|---|---|---|
| QPushButton | clicked | 按钮被点击 |
| QLineEdit | textChanged | 文本内容变化 |
| QComboBox | currentIndexChanged | 下拉选项改变 |
| QSlider | valueChanged | 滑块位置变化 |
你还可以自定义信号。比如在镜头测试中,当图像采集完成时,我习惯发射一个自定义信号:
from PyQt5.QtCore import pyqtSignal, QObject
class CameraController(QObject):
image_captured = pyqtSignal(str) # 自定义信号,传递图片路径
def capture(self):
# 采集图像...
self.image_captured.emit('/path/to/image.jpg')
4. 第一个窗口程序
好了,理论说完了,我们来写第一个程序。这个程序很简单:一个窗口,上面有个按钮,点击按钮就显示"Hello, 镜头测试系统!"
完整代码如下:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QVBoxLayout
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 创建控件
self.label = QLabel('等待点击...')
self.button = QPushButton('点击我')
# 连接信号与槽
self.button.clicked.connect(self.on_button_clicked)
# 布局
layout = QVBoxLayout()
layout.addWidget(self.label)
layout.addWidget(self.button)
self.setLayout(layout)
# 窗口设置
self.setWindowTitle('第一个PyQt5程序')
self.resize(300, 200)
def on_button_clicked(self):
self.label.setText('Hello, 镜头测试系统!')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
运行这段代码,你会看到一个300x200的窗口。点击按钮,标签文字就会变化。嗯,就是这么简单。
这里有个细节要注意:QApplication必须在使用任何Qt控件之前创建。它管理着整个应用程序的资源,包括事件循环、剪贴板、字体设置等。如果你忘了这行,程序会直接报错。
知识体系总览
为了让你更直观地理解本章内容,我画了一张图:
这张图把本章的三个核心内容串起来了。你想想看,安装是基础,Qt Designer帮你快速搭界面,信号与槽让界面"活"起来——三者缺一不可。
好了,今天的分享就到这里。记住:动手写代码比看十遍教程都管用。打开你的编辑器,把那个第一个窗口程序跑起来,然后试着改改按钮的文字、换个信号试试。遇到问题很正常,我当年也是这么过来的。