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 文件
      • 5. 动态加载 vs 静态转换
      • 6. 常见问题
        • 问题 1:找不到 pyuic5 命令
        • 问题 2:控件布局错乱
        • 问题 3:中文显示乱码
    • 第三章:信号与槽
      • 1. 信号与槽的基本概念
      • 2. 基本用法
        • 示例 1:按钮点击事件
      • 3. 信号与槽的多种连接方式
        • 方式 1:直接连接(常用)
        • 方式 2:使用装饰器 @pyqtSlot(明确参数类型)
        • 方式 3:自动连接(通过命名规则)
      • 4. 带参数的信号与槽
        • 示例:传递数据
      • 5. 常用控件的信号
      • 6. 自定义信号
      • 7. 信号与槽的高级用法
        • (1)断开连接
        • (2)连接多个槽
        • (3)跨线程通信
      • 8. 使用 Qt Designer 连接信号与槽
      • 9. 常见问题
        • 问题 1:信号未触发槽函数
        • 问题 2:参数类型不匹配
        • 问题 3:信号重复触发

绪论:PyQt5是什么

PyQt5 是一个基于 Qt 框架的 Python GUI 开发库,用于快速构建跨平台桌面应用程序。


1. 核心定义

  • 本质:Qt 框架的 Python 绑定,通过 SIP 工具将 C++ 的 Qt 库转换为 Python 接口。
  • 用途:开发功能丰富、界面美观的桌面应用,支持复杂交互和多媒体功能。
    PyQt5_logo

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 命令(可能需要配置环境变量)。

2. Qt Designer 界面概览

Qt Designer 主界面分为以下几个区域:

  • 左侧:控件工具箱(如按钮、标签、输入框等)。
  • 右侧:属性编辑器(修改控件的属性,如大小、文字、样式等)。
  • 中间:主设计区域(拖拽控件到窗口上)。
  • 顶部:布局工具栏(设置控件对齐、间距等)。

屏幕截图 2025-02-16 162941.png


3. 设计一个简单界面

步骤 1:创建主窗口

  1. 打开 Qt Designer 后,选择 Main Window 模板,点击 Create
  2. 主窗口默认包含菜单栏、状态栏和中心区域。

步骤 2:添加控件

  1. 从左侧控件栏拖拽组件到窗口(例如:LabelPushButtonLineEdit)。
  2. 选中控件后,在右侧属性编辑器中修改属性:
    • 对象名(objectName):控件的唯一标识(代码中会用到,如 self.pushButton)。
    • 文本(text):显示的文字(如 "点击我")。
    • 尺寸(geometry):调整控件位置和大小。

步骤 3:设置布局

  1. 选中多个控件,点击顶部布局工具(如 水平布局垂直布局网格布局),避免控件重叠。
  2. 如果主窗口未自动填充布局,右键空白处选择 布局 > 栅格布局

步骤 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 或环境变量未配置。
  • 解决
    1. 确认 PyQt5 已安装:pip show pyqt5
    2. 找到 pyuic5.exe 路径(通常在 Python安装目录/Scripts 下),将其添加到系统环境变量。

问题 2:控件布局错乱

  • 解决
    • 使用布局管理器(如栅格布局)替代手动调整位置。
    • 设置控件的最小/最大尺寸(MinimumSize/MaximumSize)。

问题 3:中文显示乱码

  • 解决
    在代码开头添加:

    import sys
    from PyQt5.QtCore import QTextCodec
    QTextCodec.setCodecForLocale(QTextCodec.codecForName("UTF-8"))
    

第三章:信号与槽

在 PyQt5 中,**信号(Signal)槽(Slot)**是用于对象间通信的核心机制,它允许控件(如按钮、输入框等)在特定事件(如点击、输入)发生时,触发其他对象(如窗口、函数)的响应逻辑。以下是详细用法和示例:


1. 信号与槽的基本概念

  • 信号(Signal)
    由控件(或对象)在特定事件发生时发出的通知(例如:按钮被点击时发出 clicked 信号)。
  • 槽(Slot)
    接收信号并执行逻辑的函数或方法(例如:弹出一个对话框或更新标签文本)。

信号与槽.png


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 会自动连接。
例如:按钮的 objectNamebtnSubmit,信号是 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 连接信号与槽

  1. 在 Qt Designer 中直接绑定

    • 右键控件 > Go to slot > 选择信号(如 clicked()),自动生成槽函数框架。
  2. 生成代码后手动连接
    在生成的 .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() 断开旧的连接,或在连接前检查是否已连接。

PyQt5 从零入门
http://ddxd.xyz//archives/pyqt5-cong-ling-ru-men
作者
Administrator
发布于
2025年02月16日
许可协议