PyQt5 从零入门
PyQt5 从零入门
PyQt5 是一个用于创建图形用户界面(GUI)的 Python 库,基于 Qt 框架(C++ 编写)。它功能强大且跨平台(支持 Windows、macOS、Linux),适合开发桌面应用程序。
- PyQt5 从零入门
- 绪论:PyQt5是什么
- 1. 核心定义
- 2. 核心特点
- 3. 适用场景
- 4. 对比 PySide2
- 第一章:配置环境
- 1、创建虚拟环境
- 2. 激活虚拟环境
- 3. 安装 PyQt5 及相关工具
- (1) 通过 conda 安装(推荐)
- (2) 通过 pip 安装
- 4. 验证安装
- (1) 检查 PyQt5 版本
- (2) 运行简单示例
- 第二章:Qt Designer
- 1. 安装与启动 Qt Designer
- 2. Qt Designer 界面概览
- 3. 设计一个简单界面
- 步骤 1:创建主窗口
- 步骤 2:添加控件
- 步骤 3:设置布局
- 步骤 4:保存为
.ui
文件
- 4. 将
.ui
文件转换为 Python 代码- 方法 1:使用命令行工具
pyuic5
- 方法 2:在代码中动态加载
.ui
文件
- 方法 1:使用命令行工具
- 5. 动态加载 vs 静态转换
- 6. 常见问题
- 问题 1:找不到
pyuic5
命令 - 问题 2:控件布局错乱
- 问题 3:中文显示乱码
- 问题 1:找不到
- 第三章:信号与槽
- 1. 信号与槽的基本概念
- 2. 基本用法
- 示例 1:按钮点击事件
- 3. 信号与槽的多种连接方式
- 方式 1:直接连接(常用)
- 方式 2:使用装饰器
@pyqtSlot
(明确参数类型) - 方式 3:自动连接(通过命名规则)
- 4. 带参数的信号与槽
- 示例:传递数据
- 5. 常用控件的信号
- 6. 自定义信号
- 7. 信号与槽的高级用法
- (1)断开连接
- (2)连接多个槽
- (3)跨线程通信
- 8. 使用 Qt Designer 连接信号与槽
- 9. 常见问题
- 问题 1:信号未触发槽函数
- 问题 2:参数类型不匹配
- 问题 3:信号重复触发
- 绪论:PyQt5是什么
绪论:PyQt5是什么
PyQt5 是一个基于 Qt 框架的 Python GUI 开发库,用于快速构建跨平台桌面应用程序。
1. 核心定义
- 本质:Qt 框架的 Python 绑定,通过 SIP 工具将 C++ 的 Qt 库转换为 Python 接口。
- 用途:开发功能丰富、界面美观的桌面应用,支持复杂交互和多媒体功能。
2. 核心特点
特点 | 说明 |
---|---|
跨平台 | 一次编写,支持 Windows、macOS、Linux。 |
丰富的组件库 | 提供 600+ 控件(按钮、表格、图表、浏览器等),覆盖常见 GUI 需求。 |
信号与槽机制 | 事件驱动设计,实现对象间高效通信(如按钮点击触发函数)。 |
强大的扩展性 | 支持 OpenGL 绘图、Web 嵌入(Chromium)、数据库操作、多线程、多媒体等。 |
Qt Designer 工具 | 可视化拖拽设计界面,生成 .ui 文件,提升开发效率。 |
样式自定义(QSS) | 类似 CSS 的语法,轻松美化控件外观。 |
协议与生态 | 采用 GPL 协议(商业用途需购买授权);社区资源丰富,文档齐全。 |
3. 适用场景
- 跨平台桌面应用:需兼容多操作系统的工具软件。
- 数据可视化:结合 Matplotlib 或 PyQtGraph 展示图表。
- 嵌入式界面:工业控制、仪器仪表的前端交互。
- 多媒体应用:音视频播放器、图像处理工具。
- 快速原型开发:通过 Qt Designer 快速搭建界面原型。
4. 对比 PySide2
- 协议差异:PyQt5 为 GPL,PySide2 为 LGPL(商业友好)。
- 语法差异:二者 API 高度相似,但信号定义方式不同(PyQt5 用
pyqtSignal
,PySide2 用Signal
)。
总结:PyQt5 适合需要 复杂交互、跨平台兼容 或 高性能渲染 的桌面应用开发,学习曲线适中,功能全面。
第一章:配置环境
1、创建虚拟环境
使用anaconda创建虚拟环境,如果你还不了解anaconda请先了解anaconda并熟悉基本的命令。
打开终端(Windows 使用 Anaconda Prompt,macOS/Linux 使用终端),执行以下命令:
conda create -n pyqt5_env python=3.8
-n pyqt5_env
:指定环境名称为pyqt5_env
(可自定义)。python=3.8
:指定 Python 版本(PyQt5 兼容 Python 3.6+)。
2. 激活虚拟环境
conda activate pyqt5_env # Windows/macOS/Linux
3. 安装 PyQt5 及相关工具
(1) 通过 conda 安装(推荐)
conda install -c conda-forge pyqt=5
-c conda-forge
:指定 conda-forge 频道(提供最新版本)。
(2) 通过 pip 安装
pip install pyqt5 pyqt5-tools
pyqt5
:主库。pyqt5-tools
:包含 Qt Designer(可视化界面设计工具)。
4. 验证安装
(1) 检查 PyQt5 版本
在 Python 交互环境中输入:
import PyQt5
print(PyQt5.__version__) # 输出 PyQt5 版本
(2) 运行简单示例
创建一个文件 test.py
,写入以下代码:
import sys
from PyQt5.QtWidgets import QApplication, QLabel
app = QApplication(sys.argv)
label = QLabel("PyQt5 环境配置成功!")
label.show()
sys.exit(app.exec_())
运行代码:
python test.py
如果弹出窗口显示文字,则环境配置成功。
第二章:Qt Designer
1. 安装与启动 Qt Designer
- 安装方式:
-
如果你已经安装了 PyQt5,通常会自带
Qt Designer
。 -
如果没有,可通过以下命令单独安装(Windows 用户可能需要此步骤):
pip install pyqt5-tools
-
- 启动 Qt Designer:
- Windows:在 Python 安装目录的
Scripts
文件夹中找到designer.exe
(路径类似D:\ANACONDA\Library\bin\designer.exe)。 - Mac/Linux:在终端直接运行
designer
命令(可能需要配置环境变量)。
- Windows:在 Python 安装目录的
2. Qt Designer 界面概览
Qt Designer 主界面分为以下几个区域:
- 左侧:控件工具箱(如按钮、标签、输入框等)。
- 右侧:属性编辑器(修改控件的属性,如大小、文字、样式等)。
- 中间:主设计区域(拖拽控件到窗口上)。
- 顶部:布局工具栏(设置控件对齐、间距等)。
3. 设计一个简单界面
步骤 1:创建主窗口
- 打开 Qt Designer 后,选择 Main Window 模板,点击 Create。
- 主窗口默认包含菜单栏、状态栏和中心区域。
步骤 2:添加控件
- 从左侧控件栏拖拽组件到窗口(例如:
Label
、PushButton
、LineEdit
)。 - 选中控件后,在右侧属性编辑器中修改属性:
- 对象名(objectName):控件的唯一标识(代码中会用到,如
self.pushButton
)。 - 文本(text):显示的文字(如 "点击我")。
- 尺寸(geometry):调整控件位置和大小。
- 对象名(objectName):控件的唯一标识(代码中会用到,如
步骤 3:设置布局
- 选中多个控件,点击顶部布局工具(如 水平布局、垂直布局、网格布局),避免控件重叠。
- 如果主窗口未自动填充布局,右键空白处选择 布局 > 栅格布局。
步骤 4:保存为 .ui
文件
点击菜单栏 File > Save As,保存为 my_ui.ui
文件(XML 格式的界面描述文件)。
4. 将 .ui
文件转换为 Python 代码
方法 1:使用命令行工具 pyuic5
# 转换 .ui 文件为 .py 文件
pyuic5 -x my_ui.ui -o my_ui.py
-x
参数会生成一个可直接运行的示例代码。- 生成后的
my_ui.py
包含界面类(如Ui_MainWindow
)。
方法 2:在代码中动态加载 .ui
文件
无需转换,直接在代码中加载 .ui
文件(推荐动态修改时使用):
from PyQt5 import QtWidgets, uic
class MyWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi("my_ui.ui", self) # 加载 UI 文件
# 绑定按钮点击事件(假设按钮的 objectName 是 "pushButton")
self.pushButton.clicked.connect(self.on_click)
def on_click(self):
print("按钮被点击了!")
if __name__ == "__main__":
app = QtWidgets.QApplication([])
window = MyWindow()
window.show()
app.exec_()
5. 动态加载 vs 静态转换
方式 | 动态加载 .ui |
静态转换 .py |
---|---|---|
优点 | 修改界面无需重新生成代码 | 代码可读性高,便于直接修改 |
缺点 | 运行时依赖 .ui 文件 |
每次修改界面需重新转换 |
适用场景 | 快速原型开发、频繁修改界面 | 需要直接操作界面类逻辑时 |
6. 常见问题
问题 1:找不到 pyuic5
命令
- 原因:未正确安装 PyQt5 或环境变量未配置。
- 解决:
- 确认 PyQt5 已安装:
pip show pyqt5
。 - 找到
pyuic5.exe
路径(通常在Python安装目录/Scripts
下),将其添加到系统环境变量。
- 确认 PyQt5 已安装:
问题 2:控件布局错乱
- 解决:
- 使用布局管理器(如栅格布局)替代手动调整位置。
- 设置控件的最小/最大尺寸(MinimumSize/MaximumSize)。
问题 3:中文显示乱码
-
解决:
在代码开头添加:import sys from PyQt5.QtCore import QTextCodec QTextCodec.setCodecForLocale(QTextCodec.codecForName("UTF-8"))
第三章:信号与槽
在 PyQt5 中,**信号(Signal)与槽(Slot)**是用于对象间通信的核心机制,它允许控件(如按钮、输入框等)在特定事件(如点击、输入)发生时,触发其他对象(如窗口、函数)的响应逻辑。以下是详细用法和示例:
1. 信号与槽的基本概念
- 信号(Signal):
由控件(或对象)在特定事件发生时发出的通知(例如:按钮被点击时发出clicked
信号)。 - 槽(Slot):
接收信号并执行逻辑的函数或方法(例如:弹出一个对话框或更新标签文本)。
2. 基本用法
示例 1:按钮点击事件
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.button = QPushButton("Click Me", self)
self.label = QLabel("Waiting...", self)
# 连接按钮的 clicked 信号到槽函数 on_click
self.button.clicked.connect(self.on_click)
def on_click(self):
self.label.setText("Button clicked!")
if __name__ == "__main__":
app = QApplication([])
window = MyWindow()
window.show()
app.exec_()
3. 信号与槽的多种连接方式
方式 1:直接连接(常用)
button.clicked.connect(slot_function)
方式 2:使用装饰器 @pyqtSlot
(明确参数类型)
from PyQt5.QtCore import pyqtSlot
class MyWindow(QWidget):
@pyqtSlot() # 显式声明无参数的槽
def on_click(self):
print("Button clicked!")
方式 3:自动连接(通过命名规则)
如果槽函数命名为 on_控件对象名_信号名
,PyQt5 会自动连接。
例如:按钮的 objectName
是 btnSubmit
,信号是 clicked
,则槽函数名为 on_btnSubmit_clicked
。
4. 带参数的信号与槽
示例:传递数据
from PyQt5.QtCore import pyqtSignal
class MyWidget(QWidget):
# 定义一个带参数的信号(参数类型为 int)
value_changed = pyqtSignal(int)
def __init__(self):
super().__init__()
self.value = 0
def increment(self):
self.value += 1
self.value_changed.emit(self.value) # 发射信号并传递参数
# 使用信号
widget = MyWidget()
widget.value_changed.connect(lambda x: print(f"Value: {x}"))
widget.increment() # 输出 "Value: 1"
5. 常用控件的信号
控件 | 常用信号 | 说明 |
---|---|---|
QPushButton | clicked |
按钮被点击 |
QLineEdit | textChanged(str) |
输入框文本变化 |
QComboBox | currentIndexChanged(int) |
下拉选项变化 |
QSlider | valueChanged(int) |
滑块值变化 |
QCheckBox | stateChanged(int) |
复选框状态变化 |
6. 自定义信号
from PyQt5.QtCore import QObject, pyqtSignal
class MyEmitter(QObject):
# 定义一个带字符串参数的信号
message_sent = pyqtSignal(str)
def send_message(self, text):
self.message_sent.emit(text)
# 使用自定义信号
emitter = MyEmitter()
emitter.message_sent.connect(lambda msg: print(f"Received: {msg}"))
emitter.send_message("Hello PyQt5!") # 输出 "Received: Hello PyQt5!"
7. 信号与槽的高级用法
(1)断开连接
button.clicked.disconnect(slot_function)
(2)连接多个槽
button.clicked.connect(slot1)
button.clicked.connect(slot2)
(3)跨线程通信
在 PyQt5 中,信号与槽是线程安全的,可以用于跨线程通信:
from PyQt5.QtCore import QThread
class WorkerThread(QThread):
finished = pyqtSignal()
def run(self):
# 执行耗时操作
self.finished.emit() # 完成后发射信号
# 主线程中连接信号
worker = WorkerThread()
worker.finished.connect(lambda: print("Task completed!"))
worker.start()
8. 使用 Qt Designer 连接信号与槽
-
在 Qt Designer 中直接绑定:
- 右键控件 > Go to slot > 选择信号(如
clicked()
),自动生成槽函数框架。
- 右键控件 > Go to slot > 选择信号(如
-
生成代码后手动连接:
在生成的.py
文件中补充逻辑:class Ui_MainWindow(object): def setupUi(self, MainWindow): # ... 自动生成的代码 ... self.pushButton.clicked.connect(MainWindow.on_button_click) class MainWindow(QMainWindow, Ui_MainWindow): def on_button_click(self): print("Button clicked via Qt Designer!")
9. 常见问题
问题 1:信号未触发槽函数
- 可能原因:
- 未正确连接信号与槽(检查
.connect()
语句)。 - 槽函数命名不符合自动连接规则(如
on_控件名_信号名
)。
- 未正确连接信号与槽(检查
问题 2:参数类型不匹配
-
解决:
使用@pyqtSlot
装饰器明确参数类型:@pyqtSlot(int) def on_value_changed(self, value): print(f"Value: {value}")
问题 3:信号重复触发
- 解决:
使用disconnect()
断开旧的连接,或在连接前检查是否已连接。