Python3 PyQt

PyQt 是 Python 绑定 Qt 框架的 GUI(图形用户界面)开发库,相比 Tkinter,它功能更强大、界面更美观,支持跨平台(Windows/Mac/Linux),是 Python 桌面应用开发的首选工具之一。本文以 PyQt5 为例,从环境搭建、基础窗口到实战案例,系统讲解 PyQt 的核心使用方法。

一、核心认知:PyQt5 的定位与优势

1. PyQt5 vs 其他 GUI 库

特性PyQt5Tkinter(Python 内置)wxPython
功能丰富度 极高(支持 Qt 全功能) 基础(仅核心组件) 中高
界面美观度 现代、可自定义 简陋、风格老旧 中等
跨平台兼容性 完美支持 基本支持 较好
学习曲线 中等 中高
适用场景 复杂桌面应用、商用软件 简单小工具、教学 中型桌面应用

2. 核心概念

  • QApplication:应用程序核心,管理全局资源,每个 PyQt 程序必须有且仅有一个;
  • QWidget:所有可视化组件的基类(如窗口、按钮、输入框);
  • QMainWindow:带菜单栏、工具栏、状态栏的标准主窗口;
  • 信号与槽(Signal & Slot):PyQt 的核心通信机制,组件触发 “信号”(如按钮点击),绑定的 “槽函数”(自定义函数)响应事件。

二、环境搭建:快速安装与验证

1. 安装 PyQt5

PyQt5 可通过 pip 直接安装,命令如下:
  
# 安装核心库
pip install PyQt5
# 安装Qt设计器(可视化界面编辑工具,可选但推荐)
pip install pyqt5-tools
 

2. 验证安装

运行以下代码,若弹出空白窗口则安装成功:
 
import sys
from PyQt5.QtWidgets import QApplication, QWidget

# 1. 创建应用程序对象
app = QApplication(sys.argv)

# 2. 创建基础窗口
window = QWidget()
window.setWindowTitle("第一个PyQt窗口")  # 设置窗口标题
window.resize(400, 300)  # 设置窗口大小(宽x高)
window.show()  # 显示窗口(默认隐藏)

# 3. 进入应用程序主循环(监听事件,如点击、关闭)
sys.exit(app.exec_())
 

三、基础窗口:核心组件与布局管理

1. 核心组件使用(按钮、标签、输入框)

PyQt 的 GUI 开发核心是 “组件 + 布局 + 信号槽”,以下示例整合常用基础组件:
  
import sys
from PyQt5.QtWidgets import (
    QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout
)

# 定义窗口类(继承QWidget)
class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()  # 初始化界面

    def initUI(self):
        # 1. 创建组件
        # 标签(显示文本)
        self.label = QLabel("请输入内容:", self)
        # 输入框(单行文本输入)
        self.input = QLineEdit(self)
        # 按钮(触发事件)
        self.btn = QPushButton("点击获取输入内容", self)
        
        # 2. 绑定信号与槽(按钮点击 → 执行get_input函数)
        self.btn.clicked.connect(self.get_input)

        # 3. 布局管理(垂直布局,避免组件重叠)
        layout = QVBoxLayout()  # 垂直布局
        layout.addWidget(self.label)  # 添加标签
        layout.addWidget(self.input)  # 添加输入框
        layout.addWidget(self.btn)    # 添加按钮
        self.setLayout(layout)       # 设置窗口布局

        # 4. 窗口基础设置
        self.setWindowTitle("基础组件示例")
        self.resize(400, 200)

    # 槽函数:响应按钮点击
    def get_input(self):
        text = self.input.text()  # 获取输入框内容
        self.label.setText(f"你输入的内容:{text}")  # 更新标签文本

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())
 

2. 关键知识点解释

  • 布局管理器:PyQt 提供 4 种核心布局,解决组件位置和大小自适应问题:
    • QVBoxLayout:垂直布局(组件从上到下排列);
    • QHBoxLayout:水平布局(组件从左到右排列);
    • QGridLayout:网格布局(按行 / 列排列,适合复杂界面);
    • QFormLayout:表单布局(标签 + 输入框成对排列);
  • 信号与槽组件.信号.connect(槽函数) 是核心语法,常用信号:
    • 按钮:clicked(点击);
    • 输入框:textChanged(文本变化)、returnPressed(按回车);
    • 窗口:closeEvent(关闭窗口);
  • 组件常用方法
    • 标签(QLabel):setText()(设置文本)、setTextFormat()(设置富文本);
    • 输入框(QLineEdit):text()(获取文本)、setPlaceholderText()(提示文字);
    • 按钮(QPushButton):setText()(按钮文字)、setEnabled()(是否可用)。

四、核心进阶:QMainWindow(带菜单栏的主窗口)

实际桌面应用多使用QMainWindow,它内置菜单栏、工具栏、状态栏,更符合用户习惯:
  
import sys
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QTextEdit, QAction, qApp
)
from PyQt5.QtGui import QIcon

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # 1. 中心组件(文本编辑框)
        textEdit = QTextEdit()
        self.setCentralWidget(textEdit)  # 设置为中心组件(自动填充窗口)

        # 2. 菜单栏
        menubar = self.menuBar()
        # 创建“文件”菜单
        fileMenu = menubar.addMenu('文件')
        
        # 创建“退出”动作(带图标和快捷键)
        exitAct = QAction(QIcon(), '退出', self)  # 图标可替换为本地路径,如'icon.png'
        exitAct.setShortcut('Ctrl+Q')  # 设置快捷键
        exitAct.triggered.connect(qApp.quit)  # 绑定退出应用
        
        # 将动作添加到菜单
        fileMenu.addAction(exitAct)

        # 3. 状态栏
        self.statusBar().showMessage('就绪')  # 显示状态提示

        # 4. 窗口设置
        self.setWindowTitle('主窗口示例')
        self.resize(800, 600)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
 

五、实战案例:简易文本编辑器

整合以上知识点,实现一个带 “打开文件”“保存文件”“退出” 功能的简易文本编辑器:
 
import sys
import os
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QTextEdit, QAction, QFileDialog
)
from PyQt5.QtGui import QIcon

class TextEditor(QMainWindow):
    def __init__(self):
        super().__init__()
        self.current_file = None  # 记录当前打开的文件路径
        self.initUI()

    def initUI(self):
        # 中心组件:文本编辑框
        self.text_edit = QTextEdit()
        self.setCentralWidget(self.text_edit)

        # 菜单栏
        menubar = self.menuBar()
        file_menu = menubar.addMenu('文件')

        # 1. 打开文件动作
        open_act = QAction('打开文件', self)
        open_act.setShortcut('Ctrl+O')
        open_act.triggered.connect(self.open_file)
        file_menu.addAction(open_act)

        # 2. 保存文件动作
        save_act = QAction('保存文件', self)
        save_act.setShortcut('Ctrl+S')
        save_act.triggered.connect(self.save_file)
        file_menu.addAction(save_act)

        # 3. 退出动作
        exit_act = QAction('退出', self)
        exit_act.setShortcut('Ctrl+Q')
        exit_act.triggered.connect(self.close)
        file_menu.addAction(exit_act)

        # 状态栏
        self.statusBar().showMessage('就绪')

        # 窗口设置
        self.setWindowTitle('简易文本编辑器')
        self.resize(800, 600)

    # 打开文件
    def open_file(self):
        # 弹出文件选择对话框
        file_path, _ = QFileDialog.getOpenFileName(
            self, '打开文件', os.getcwd(), '文本文件 (*.txt);;所有文件 (*.*)'
        )
        if file_path:
            self.current_file = file_path
            # 读取文件内容并显示
            with open(file_path, 'r', encoding='utf-8') as f:
                self.text_edit.setText(f.read())
            self.statusBar().showMessage(f'已打开:{file_path}')

    # 保存文件
    def save_file(self):
        if not self.current_file:
            # 未打开文件,弹出“另存为”对话框
            file_path, _ = QFileDialog.getSaveFileName(
                self, '保存文件', os.getcwd(), '文本文件 (*.txt);;所有文件 (*.*)'
            )
            if not file_path:
                return
            self.current_file = file_path
        # 写入文件
        with open(self.current_file, 'w', encoding='utf-8') as f:
            f.write(self.text_edit.toPlainText())
        self.statusBar().showMessage(f'已保存:{self.current_file}')

if __name__ == "__main__":
    app = QApplication(sys.argv)
    editor = TextEditor()
    editor.show()
    sys.exit(app.exec_())
 

六、避坑指南:常见问题与解决方法

1. 界面无响应 / 卡死

  • 原因:耗时操作(如文件读写、网络请求)放在主线程,阻塞 GUI 事件循环;
  • 解决:使用QThread创建子线程处理耗时操作,通过信号槽与主线程通信。

2. 布局失效(组件重叠 / 不显示)

  • 原因:未给窗口设置布局,或组件未添加到布局中;
  • 解决:确保所有组件通过layout.addWidget()添加,且窗口调用setLayout(layout)

3. 信号槽绑定失败

  • 原因:槽函数参数不匹配、组件未初始化就绑定信号;
  • 解决:
    • 信号带参数时,槽函数需对应接收(如textChanged(str));
    • 确保在__init__中先初始化组件,再绑定信号。

4. 打包成 exe 后运行报错

  • 原因:缺少 Qt 运行库或资源文件;
  • 解决:使用pyinstaller打包时添加参数:
    pyinstaller -F -w -i icon.ico your_script.py
    # -F:打包为单个exe;-w:无控制台窗口;-i:设置图标
    

posted on 2025-12-24 09:31  小陶coding  阅读(2)  评论(0)    收藏  举报