PySide6 + Qt Designer + PyCharm 完整开发流程

PyCharm 对 Python 桌面开发有更完善的支持,包括智能代码补全、断点调试、集成终端、版本控制等功能,结合 Qt Designer 的可视化 UI 设计,是工业级上位机开发的首选组合。以下是完全适配 PyCharm 的标准化开发流程。

一、环境准备与 PyCharm 配置

1. 创建项目并配置虚拟环境(必做)

PyCharm 强烈推荐使用虚拟环境隔离项目依赖,避免版本冲突:

  1. 打开 PyCharm → 新建项目 (New Project)
  2. 选择项目位置,命名为test_equipment_app(示例)
  3. 勾选 "New environment using Virtualenv",保持默认 Python 解释器
  4. 取消勾选 "Create a main.py welcome script"
  5. 点击 "Create" 完成项目创建

2. 安装 PySide6 核心依赖

在 PyCharm 底部的Terminal终端中执行:

bash 复制代码
# 安装指定稳定版本(推荐6.7.2,与STM32上位机兼容性最好)
pip install pyside6==6.7.2

# 验证安装(终端执行)
python -c "import PySide6; print(f'PySide6版本: {PySide6.__version__}')"

3. 配置 PyCharm 外部工具(核心步骤)

这是 PyCharm 与 Qt Designer 联动的关键,配置后可一键打开设计器、转换 UI / 资源文件:

步骤 1:打开外部工具配置界面
  • 菜单栏:File → Settings → Tools → External Tools
  • 点击左上角+号,依次添加以下 3 个工具
步骤 2:添加 Qt Designer 工具
配置项 说明
Name Qt Designer 工具显示名称
Program pyside6-designer 系统自动识别的命令
Arguments $FilePath$ 直接打开当前选中的.ui 文件
Working directory $FileDir$ 工作目录为文件所在目录
Advanced Options 取消勾选 "Synchronize files after execution" 避免不必要的文件同步
步骤 3:添加 UI 转 Python 工具
配置项
Name UI 转 Python
Program pyside6-uic
Arguments $FileName$ -o $FileNameWithoutExtension$_ui.py --from-imports
Working directory $FileDir$
步骤 4:添加资源转 Python 工具
配置项
Name 资源转 Python
Program pyside6-rcc
Arguments $FileName$ -o $FileNameWithoutExtension$_rc.py
Working directory $FileDir$
配置完成验证

右键点击项目中任意位置 → 选择External Tools,能看到刚才添加的 3 个工具即配置成功。

4. 安装 PyCharm 增强插件(推荐)

  • PySide6 Plugin:提供 UI 文件预览、信号槽导航、QSS 语法高亮
  • .ignore:自动生成.gitignore 文件,排除__pycache__、dist 等目录
  • Rainbow Brackets:彩虹括号,提升代码可读性

二、PyCharm 专属项目结构(最佳实践)

创建以下目录结构,并右键点击根目录 → Mark Directory as → Sources Root(解决导入红色波浪线问题):

bash 复制代码
test_equipment_app/
├── main.py                # 程序唯一入口
├── ui/                    # 自动生成的UI代码(禁止手动修改)
│   ├── main_window.ui     # Qt Designer设计文件
│   ├── main_window_ui.py  # uic转换后的Python代码
│   ├── setting_dialog.ui
│   └── setting_dialog_ui.py
├── views/                 # UI逻辑层(信号槽绑定、界面交互)
│   ├── main_window.py     # 主窗口逻辑类
│   └── setting_dialog.py  # 设置对话框逻辑类
├── core/                  # 核心业务逻辑(纯Python,无UI依赖)
│   ├── serial_port.py     # 串口通信(STM32/FPGA)
│   ├── data_processor.py  # 测试数据处理
│   └── test_case.py       # 测试用例执行
├── resources/             # 资源文件
│   ├── icons/             # 按钮图标、窗口图标
│   ├── qss/               # 样式表文件
│   └── resources.qrc      # Qt资源清单
├── config/                # 配置文件
│   └── app_config.ini     # 串口参数、测试参数
├── tests/                 # 单元测试
├── requirements.txt       # 依赖清单
└── .gitignore             # Git忽略文件

三、Qt Designer UI 设计流程(PyCharm 集成)

1. 快速启动 Qt Designer

在 PyCharm 中右键点击ui/目录 → External Tools → Qt Designer,直接在该目录下创建 UI 文件。

2. 核心设计规范(针对测试设备上位机)

  1. 选择正确的窗口模板

    • 主窗口:Main Window(带菜单栏、工具栏、状态栏,适合主界面)
    • 参数设置:Dialog with Buttons Right(带确定 / 取消按钮)
    • 自定义控件:Widget(如串口配置面板、数据显示面板)
  2. 控件命名规范(强制) : 后续代码通过objectName访问控件,必须统一命名:

控件类型 前缀 示例
QPushButton btn_ btn_connect_serial、btn_start_test
QLineEdit txt_ txt_serial_port、txt_baud_rate
QComboBox cbx_ cbx_baud_rate、cbx_parity
QLabel lbl_ lbl_status、lbl_test_result
QTableWidget tbl_ tbl_test_data
QCheckBox chk_ chk_auto_save
  1. 布局管理(关键)

    • 绝对禁止使用拖拽定位(窗口缩放必错位)
    • 优先使用QVBoxLayout(垂直)和QHBoxLayout(水平)
    • 复杂界面使用QGridLayout(网格)
    • 最后点击主窗口空白处 → 右键 → 布局 → 选择整体布局
    • 通过Layout属性调整间距 (margin) 和边距 (spacing)
  2. 保存 UI 文件 :保存到ui/目录,命名为main_window.ui

四、UI 文件转换与代码集成

1. 一键转换 UI 文件

在 PyCharm 中右键点击ui/main_window.uiExternal Tools → UI转Python,自动生成main_window_ui.py

重要提醒

  • 绝对不要手动修改_ui.py文件,每次 UI 修改后重新转换即可
  • 转换时自动添加的--from-imports参数会生成相对导入,避免路径问题

2. 创建视图逻辑类(UI 与逻辑分离)

views/目录下创建main_window.py,继承自 Qt 基类和自动生成的 UI 类:

python 复制代码
from PySide6.QtWidgets import QMainWindow, QMessageBox
from PySide6.QtCore import Qt
from ui.main_window_ui import Ui_MainWindow
from core.serial_port import SerialPortManager

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        # 初始化UI(自动创建所有控件)
        self.setupUi(self)
        # 设置窗口标题和大小
        self.setWindowTitle("芯片测试设备上位机")
        self.resize(1200, 800)
        # 初始化业务逻辑对象
        self.serial_manager = SerialPortManager()
        # 绑定所有信号与槽
        self._connect_signals()
        # 初始化界面数据
        self._init_ui()

    def _connect_signals(self):
        """统一管理所有信号槽绑定"""
        # 串口连接按钮
        self.btn_connect_serial.clicked.connect(self.on_connect_serial_clicked)
        # 开始测试按钮
        self.btn_start_test.clicked.connect(self.on_start_test_clicked)
        # 串口接收数据信号(自定义信号)
        self.serial_manager.data_received.connect(self.on_serial_data_received)

    def _init_ui(self):
        """初始化界面显示"""
        # 初始化串口波特率下拉框
        self.cbx_baud_rate.addItems(["9600", "19200", "38400", "115200", "921600"])
        self.cbx_baud_rate.setCurrentText("115200")
        # 状态栏显示
        self.statusBar().showMessage("设备未连接")
        # 默认禁用测试按钮
        self.btn_start_test.setEnabled(False)

    # ------------------------------ 槽函数 ------------------------------
    def on_connect_serial_clicked(self):
        """串口连接按钮点击事件"""
        port = self.txt_serial_port.text().strip()
        baud_rate = int(self.cbx_baud_rate.currentText())

        if not port:
            QMessageBox.warning(self, "警告", "请输入串口号")
            return

        try:
            if self.serial_manager.is_connected():
                self.serial_manager.disconnect()
                self.btn_connect_serial.setText("连接串口")
                self.btn_start_test.setEnabled(False)
                self.statusBar().showMessage("设备已断开")
            else:
                self.serial_manager.connect(port, baud_rate)
                self.btn_connect_serial.setText("断开串口")
                self.btn_start_test.setEnabled(True)
                self.statusBar().showMessage(f"已连接到 {port} @ {baud_rate}bps")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"串口连接失败:{str(e)}")

    def on_start_test_clicked(self):
        """开始测试按钮点击事件"""
        try:
            self.serial_manager.send_command("START_TEST")
            self.statusBar().showMessage("测试进行中...")
            self.btn_start_test.setEnabled(False)
        except Exception as e:
            QMessageBox.critical(self, "错误", f"测试启动失败:{str(e)}")

    def on_serial_data_received(self, data):
        """串口数据接收事件"""
        # 在UI线程中更新数据显示
        self.tbl_test_data.append(data)
        self.statusBar().showMessage(f"收到数据:{data}")

3. 创建程序入口

在项目根目录创建main.py

python 复制代码
import sys
from PySide6.QtWidgets import QApplication
from views.main_window import MainWindow

if __name__ == "__main__":
    # 启用高DPI支持(解决4K屏幕模糊问题)
    QApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
    
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

4. 运行程序

在 PyCharm 中右键点击main.pyRun 'main',即可启动应用。

五、PyCharm 专属调试技巧(核心优势)

PyCharm 的调试功能是其最大优势,特别适合排查串口通信、数据处理等复杂问题:

1. 基础调试操作

  • 设置断点:点击代码行号左侧的空白处,出现红色圆点即断点设置成功
  • 启动调试 :右键点击main.pyDebug 'main'(快捷键 Shift+F9)
  • 单步执行:F8(步过)、F7(步入)、Shift+F8(步出)
  • 查看变量:在 Debug 面板的 Variables 窗口查看所有变量值
  • 监视表达式:在 Watches 窗口添加需要监视的变量或表达式

2. 高级调试技巧

  • 异常断点 :在 Debug 面板点击View Breakpoints → 勾选Any Exception,程序抛出异常时自动暂停
  • 条件断点 :右键点击断点 → 设置条件(如data == "TEST_PASS"),满足条件时才暂停
  • 日志断点:右键点击断点 → 取消勾选 "Suspend",勾选 "Log message to console",不暂停程序只输出日志
  • 附加到进程 :如果程序已经运行,可以通过Run → Attach to Process附加调试

3. 常见问题排查

  • 导入错误:确认根目录已标记为 Sources Root
  • UI 修改不生效:确认已右键转换 UI 文件,且运行的是最新代码
  • 串口数据不更新:检查串口通信是否在 QThread 中运行(避免阻塞 UI 线程)
  • 程序闪退:启用异常断点,定位崩溃位置

六、资源文件与样式表处理

1. 资源文件配置

  1. resources/目录创建resources.qrc
XML 复制代码
<RCC>
    <qresource prefix="/">
        <file>icons/connect.png</file>
        <file>icons/start.png</file>
        <file>qss/style.qss</file>
    </qresource>
</RCC>

2. QSS 样式表美化

  1. resources/qss/目录创建style.qss,编写样式
  2. MainWindow.__init__中加载:
python 复制代码
# 加载全局样式表
with open("resources/qss/style.qss", "r", encoding="utf-8") as f:
    self.setStyleSheet(f.read())

七、打包与分发(PyCharm 集成)

1. 安装 PyInstaller

bash 复制代码
pip install pyinstaller

2. 配置 PyCharm 打包运行配置

  1. 菜单栏:Run → Edit Configurations
  2. 点击+ → 选择Python
  3. 配置参数:
    • Name:打包应用
    • Script path:选择pyinstaller.exe路径(虚拟环境下的Scripts/pyinstaller.exe
    • Parameters:-F -w -i resources/icons/app.ico --add-data "resources/qss;resources/qss" --add-data "config;config" main.py
  4. 点击 "OK" 保存

3. 一键打包

点击 PyCharm 右上角的运行按钮,选择 "打包应用",即可自动打包。打包完成后,可执行文件生成在dist/目录下。

八、PyCharm 专属最佳实践

  1. 使用 QThread 处理耗时任务:串口通信、数据采集、测试用例执行等必须放在子线程,避免界面卡顿
python 复制代码
from PySide6.QtCore import QThread, Signal

class TestThread(QThread):
    test_finished = Signal(bool)
    progress_updated = Signal(int)

    def run(self):
        for i in range(101):
            self.progress_updated.emit(i)
            self.msleep(100)
        self.test_finished.emit(True)
  • 使用 PyCharm 的重构功能:重命名控件、方法时,PyCharm 会自动更新所有引用,避免手动修改出错

  • 代码模板 :在File → Settings → Editor → File and Code Templates中添加自定义模板,快速创建主窗口、对话框等文件

  • 版本控制 :PyCharm 集成 Git,提交时自动忽略_ui.py_rc.py__pycache__等自动生成文件

相关推荐
BAGAE17 小时前
FEC-RS前向纠错编码理论及工程实施研究
c语言·c++·qt·算法·决策树·链表
阿旭超级学得完17 小时前
Linux基础指令 四(apt,vim,git,cgdb)
linux·服务器·开发语言·数据结构·c++·git·vim
Invictus_cl17 小时前
条纹圆形进度条(彩虹色)
开发语言·前端·javascript
Vallelonga17 小时前
Rust 中的枚举
开发语言·rust
兰令水17 小时前
leecodecode【状态机DP】【2026.6.9打卡-java版本】
java·开发语言·算法
郝亚军17 小时前
win11安装python3.12.7和pycharm
ide·python·pycharm
ALINX技术博客17 小时前
【黑金云课堂】FPGA技术教程Linux开发:摄像头GPU渲染显示/Qt OpenGLES使用
linux·qt·fpga开发·gpu
资深流水灯工程师17 小时前
PyCharm 虚拟环境完整配置指南(PySide6 开发专用)
ide·python·pycharm
宸津-代码粉碎机17 小时前
Spring AI企业级实战|Agent长期记忆持久化落地,彻底解决多轮对话上下文丢失问题
java·开发语言·人工智能·后端·python·spring