Python3入门指南Python语言的特点和实际应用Python3环境搭建配置VSCode进行Python开发Python基础语法Python变量与数据类型Python数据类型转换Python解释器使用Python注释使用Python运算符Python数字类型Python字符串操作Python列表操作Python元组使用Python字典使用Python集合使用Python条件控制详解Python循环语句详解Python编程入门实践Python推导式详解Python迭代器和生成器Python with语句详解Python函数详解Python lambda(匿名函数)Python装饰器Python数据结构Python模块和包使用Python中__name__和__main__的用法Python输入输出:从基础到文件操作Python文件操作Python OS模块使用Python错误和异常处理Python面向对象编程Python命名空间和作用域Python虚拟环境:venv详细教程Python类型注解Python标准库常用模块Python正则表达式Python CGI编程Python MySQL(mysql-connector驱动)Python MySQL(PyMySQL驱动)Python网络编程Python发送邮件Python多线程编程Python XML解析Python JSON解析Python日期和时间处理Python操作MongoDBPython urllib库使用Python uWSGI 安装与配置Python pip包管理工具Python operator模块Python math模块Python requests模块HTTP请求Python random模块Python OpenAI库Python AI绘画制作Python statistics模块Python hashlib模块:哈希加密Python量化交易Python pyecharts数据可视化Python Selenium网页自动化Python BeautifulSoup网页数据提取Python Scrapy爬虫框架Python Markdown转HTMLPython sys模块Python Pickle模块:数据存储Python subprocess模块Python queue队列模块Python StringIO内存文件操作Python logging日志记录Python datetime日期时间处理Python re正则表达式Python csv表格数据处理Python threading 多线程编程Python asyncio 异步编程Python PyQt 图形界面开发Python 应用方向和常用库框架

Python PyQt 图形界面开发

PyQt 是 Python 中创建桌面应用程序的强大工具。它让你能够制作出专业外观的图形界面,就像我们日常使用的各种软件一样。无论你是想开发一个小工具,还是构建复杂的商业软件,PyQt 都能满足你的需求。


什么是 PyQt?

PyQt 是 Qt 框架的 Python 版本。Qt 本身是用 C++ 编写的跨平台应用程序框架,被很多知名软件使用,比如 Adobe Photoshop、Google Earth 等。PyQt 让 Python 开发者也能使用这个强大的框架。

PyQt 的主要版本

  • PyQt5:基于 Qt5,目前使用最广泛的版本

  • PyQt6:基于 Qt6 的最新版本,推荐新项目使用


安装 PyQt

安装 PyQt 很简单,使用 pip 命令即可:

pip install PyQt6

如果你需要可视化设计工具,还可以安装:

pip install PyQt6-Tools


第一个 PyQt 程序

让我们从一个最简单的窗口开始:

import sys
from PyQt6.QtWidgets import QApplication, QWidget

# 每个PyQt程序都需要一个QApplication实例
app = QApplication(sys.argv)

# 创建一个窗口
window = QWidget()
window.setWindowTitle("我的第一个PyQt程序")
window.resize(400, 300)  # 设置窗口大小

# 显示窗口
window.show()

# 启动事件循环
sys.exit(app.exec())

运行这段代码,你会看到一个空白的窗口。这虽然简单,但包含了 PyQt 程序的基本结构。


理解 PyQt 程序结构

一个典型的 PyQt 程序包含以下几个部分:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setup_ui()
    
    def setup_ui(self):
        # 设置窗口标题和大小
        self.setWindowTitle("PyQt示例程序")
        self.setGeometry(100, 100, 600, 400)
        
        # 创建一个按钮
        self.button = QPushButton("点击我", self)
        self.button.move(250, 180)
        self.button.clicked.connect(self.on_button_clicked)
    
    def on_button_clicked(self):
        print("按钮被点击了!")

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

这个例子展示了面向对象的编程方式,这是开发 PyQt 应用的推荐做法。


常用界面组件

PyQt 提供了丰富的界面组件,让我们来看看最常用的一些。

标签(QLabel)

标签用于显示文本或图片:

from PyQt6.QtWidgets import QLabel
from PyQt6.QtCore import Qt

label = QLabel("欢迎使用PyQt", self)
label.move(50, 50)
label.setAlignment(Qt.AlignmentFlag.AlignCenter)  # 文字居中

文本框(QLineEdit)

单行文本输入框:

from PyQt6.QtWidgets import QLineEdit

text_input = QLineEdit(self)
text_input.move(50, 100)
text_input.resize(200, 30)
text_input.setPlaceholderText("请输入用户名")  # 提示文字

按钮(QPushButton)

按钮是最常用的交互组件:

from PyQt6.QtWidgets import QPushButton

button = QPushButton("登录", self)
button.move(50, 150)
button.clicked.connect(self.login)  # 连接点击事件

def login(self):
    username = self.text_input.text()
    print(f"用户尝试登录: {username}")

多行文本编辑器(QTextEdit)

用于输入和显示多行文本:

from PyQt6.QtWidgets import QTextEdit

text_edit = QTextEdit(self)
text_edit.setGeometry(50, 200, 300, 150)
text_edit.setPlaceholderText("请输入内容...")


布局管理

手动设置每个组件的位置很麻烦,使用布局管理器可以自动排列组件。

垂直布局(QVBoxLayout)

from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, 
                            QLabel, QLineEdit, QPushButton)

class LoginWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setup_ui()
    
    def setup_ui(self):
        self.setWindowTitle("登录窗口")
        self.resize(300, 200)
        
        # 创建垂直布局
        layout = QVBoxLayout()
        
        # 创建组件
        title_label = QLabel("用户登录")
        username_label = QLabel("用户名:")
        self.username_input = QLineEdit()
        password_label = QLabel("密码:")
        self.password_input = QLineEdit()
        self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
        login_button = QPushButton("登录")
        
        # 将组件添加到布局中
        layout.addWidget(title_label)
        layout.addWidget(username_label)
        layout.addWidget(self.username_input)
        layout.addWidget(password_label)
        layout.addWidget(self.password_input)
        layout.addWidget(login_button)
        
        # 设置窗口的布局
        self.setLayout(layout)
        
        # 连接信号
        login_button.clicked.connect(self.do_login)
    
    def do_login(self):
        username = self.username_input.text()
        password = self.password_input.text()
        print(f"登录信息 - 用户名: {username}, 密码: {password}")

水平布局(QHBoxLayout)

# 在垂直布局中添加水平布局
button_layout = QHBoxLayout()

ok_button = QPushButton("确定")
cancel_button = QPushButton("取消")

button_layout.addWidget(ok_button)
button_layout.addWidget(cancel_button)

# 将水平布局添加到垂直布局中
layout.addLayout(button_layout)


信号与槽机制

信号和槽是 PyQt 的核心特性,用于处理用户交互。

基本用法

from PyQt6.QtWidgets import QCheckBox

class SignalExample(QWidget):
    def __init__(self):
        super().__init__()
        self.setup_ui()
    
    def setup_ui(self):
        self.setWindowTitle("信号与槽示例")
        self.resize(300, 200)
        
        layout = QVBoxLayout()
        
        # 复选框
        self.checkbox = QCheckBox("同意条款")
        self.checkbox.stateChanged.connect(self.on_checkbox_changed)
        
        # 按钮
        self.button = QPushButton("继续")
        self.button.setEnabled(False)  # 初始不可用
        self.button.clicked.connect(self.on_button_clicked)
        
        layout.addWidget(self.checkbox)
        layout.addWidget(self.button)
        self.setLayout(layout)
    
    def on_checkbox_changed(self, state):
        # 只有当复选框被选中时,按钮才可用
        self.button.setEnabled(state == 2)  # 2表示选中状态
    
    def on_button_clicked(self):
        print("用户点击了继续按钮")

自定义信号

from PyQt6.QtCore import pyqtSignal, QObject

class DataManager(QObject):
    # 定义自定义信号
    data_updated = pyqtSignal(str)
    data_error = pyqtSignal(str)
    
    def process_data(self, data):
        try:
            # 模拟数据处理
            result = data.upper()
            # 发射信号
            self.data_updated.emit(result)
        except Exception as e:
            self.data_error.emit(str(e))

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.data_manager = DataManager()
        self.setup_ui()
        self.connect_signals()
    
    def setup_ui(self):
        # 界面设置代码...
        pass
    
    def connect_signals(self):
        # 连接自定义信号
        self.data_manager.data_updated.connect(self.on_data_updated)
        self.data_manager.data_error.connect(self.on_data_error)
    
    def on_data_updated(self, result):
        print(f"数据处理成功: {result}")
    
    def on_data_error(self, error_msg):
        print(f"数据处理错误: {error_msg}")


使用 Qt Designer

Qt Designer 是一个可视化界面设计工具,让你可以通过拖放的方式设计界面。

使用步骤

  1. 启动 Qt Designer

  2. 设计界面并保存为 .ui 文件

  3. 将 .ui 文件转换为 Python 代码

转换命令:

pyuic6 input.ui -o output.py

在代码中使用设计的界面

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow
from output import Ui_MainWindow  # 从生成的文件导入

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.connect_signals()
    
    def connect_signals(self):
        self.ui.pushButton.clicked.connect(self.on_button_clicked)
    
    def on_button_clicked(self):
        text = self.ui.lineEdit.text()
        self.ui.label.setText(f"你好, {text}!")

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


实战:制作一个简单的记事本

让我们用 PyQt 制作一个功能完整的记事本程序。

import sys
from PyQt6.QtWidgets import (QApplication, QMainWindow, QTextEdit, 
                            QFileDialog, QMessageBox, QToolBar, QStatusBar)
from PyQt6.QtGui import QAction, QIcon
from PyQt6.QtCore import Qt

class Notepad(QMainWindow):
    def __init__(self):
        super().__init__()
        self.current_file = None
        self.setup_ui()
    
    def setup_ui(self):
        self.setWindowTitle("简易记事本")
        self.setGeometry(100, 100, 800, 600)
        
        # 创建文本编辑器
        self.text_edit = QTextEdit()
        self.setCentralWidget(self.text_edit)
        
        # 创建菜单栏
        self.create_menus()
        
        # 创建工具栏
        self.create_toolbar()
        
        # 创建状态栏
        self.statusBar().showMessage("就绪")
    
    def create_menus(self):
        menubar = self.menuBar()
        
        # 文件菜单
        file_menu = menubar.addMenu("文件")
        
        new_action = QAction("新建", self)
        new_action.setShortcut("Ctrl+N")
        new_action.triggered.connect(self.new_file)
        file_menu.addAction(new_action)
        
        open_action = QAction("打开", self)
        open_action.setShortcut("Ctrl+O")
        open_action.triggered.connect(self.open_file)
        file_menu.addAction(open_action)
        
        save_action = QAction("保存", self)
        save_action.setShortcut("Ctrl+S")
        save_action.triggered.connect(self.save_file)
        file_menu.addAction(save_action)
        
        file_menu.addSeparator()
        
        exit_action = QAction("退出", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)
        
        # 编辑菜单
        edit_menu = menubar.addMenu("编辑")
        
        copy_action = QAction("复制", self)
        copy_action.setShortcut("Ctrl+C")
        copy_action.triggered.connect(self.text_edit.copy)
        edit_menu.addAction(copy_action)
        
        paste_action = QAction("粘贴", self)
        paste_action.setShortcut("Ctrl+V")
        paste_action.triggered.connect(self.text_edit.paste)
        edit_menu.addAction(paste_action)
        
        cut_action = QAction("剪切", self)
        cut_action.setShortcut("Ctrl+X")
        cut_action.triggered.connect(self.text_edit.cut)
        edit_menu.addAction(cut_action)
    
    def create_toolbar(self):
        toolbar = QToolBar("主工具栏")
        self.addToolBar(toolbar)
        
        # 可以在这里添加工具栏按钮
        # 实际开发中可以使用图标
    
    def new_file(self):
        self.text_edit.clear()
        self.current_file = None
        self.setWindowTitle("简易记事本 - 新文件")
        self.statusBar().showMessage("新建文件")
    
    def open_file(self):
        filename, _ = QFileDialog.getOpenFileName(
            self, "打开文件", "", "文本文件 (*.txt);;所有文件 (*)"
        )
        
        if filename:
            try:
                with open(filename, 'r', encoding='utf-8') as file:
                    content = file.read()
                    self.text_edit.setText(content)
                    self.current_file = filename
                    self.setWindowTitle(f"简易记事本 - {filename}")
                    self.statusBar().showMessage(f"已打开: {filename}")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"无法打开文件: {e}")
    
    def save_file(self):
        if self.current_file:
            filename = self.current_file
        else:
            filename, _ = QFileDialog.getSaveFileName(
                self, "保存文件", "", "文本文件 (*.txt);;所有文件 (*)"
            )
        
        if filename:
            try:
                with open(filename, 'w', encoding='utf-8') as file:
                    content = self.text_edit.toPlainText()
                    file.write(content)
                    self.current_file = filename
                    self.setWindowTitle(f"简易记事本 - {filename}")
                    self.statusBar().showMessage(f"已保存: {filename}")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"无法保存文件: {e}")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    notepad = Notepad()
    notepad.show()
    sys.exit(app.exec())

这个记事本程序包含了文件操作、菜单栏、状态栏等完整功能。


高级功能扩展

使用表格(QTableWidget)

from PyQt6.QtWidgets import QTableWidget, QTableWidgetItem

class TableExample(QWidget):
    def __init__(self):
        super().__init__()
        self.setup_ui()
    
    def setup_ui(self):
        self.setWindowTitle("表格示例")
        self.resize(500, 300)
        
        layout = QVBoxLayout()
        
        # 创建表格
        self.table = QTableWidget(5, 3)  # 5行3列
        self.table.setHorizontalHeaderLabels(["姓名", "年龄", "城市"])
        
        # 添加数据
        data = [
            ["张三", "25", "北京"],
            ["李四", "30", "上海"],
            ["王五", "28", "广州"],
            ["赵六", "35", "深圳"],
            ["钱七", "22", "杭州"]
        ]
        
        for row, row_data in enumerate(data):
            for col, cell_data in enumerate(row_data):
                self.table.setItem(row, col, QTableWidgetItem(cell_data))
        
        layout.addWidget(self.table)
        self.setLayout(layout)

使用进度条(QProgressBar)

from PyQt6.QtWidgets import QProgressBar
from PyQt6.QtCore import QTimer

class ProgressExample(QWidget):
    def __init__(self):
        super().__init__()
        self.progress_value = 0
        self.setup_ui()
    
    def setup_ui(self):
        self.setWindowTitle("进度条示例")
        self.resize(400, 200)
        
        layout = QVBoxLayout()
        
        self.progress_bar = QProgressBar()
        self.progress_bar.setValue(0)
        
        start_button = QPushButton("开始进度")
        start_button.clicked.connect(self.start_progress)
        
        layout.addWidget(self.progress_bar)
        layout.addWidget(start_button)
        self.setLayout(layout)
    
    def start_progress(self):
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_progress)
        self.timer.start(100)  # 每100毫秒更新一次
    
    def update_progress(self):
        self.progress_value += 1
        self.progress_bar.setValue(self.progress_value)
        
        if self.progress_value >= 100:
            self.timer.stop()
            QMessageBox.information(self, "完成", "进度已完成!")


PyQt5 核心组件

大多数组件位于 PyQt5.QtWidgets。

高级功能(如多媒体、网络)可能需要其他模块(如 QtCore, QtGui, QtNetwork 等)。

QListView/QTableView/QTreeView 需要搭配数据模型(如 QStandardItemModel)使用,灵活性更高。

组件类别组件名称所在模块说明
基础窗口组件QWidgetQtWidgets所有用户界面对象的基类,可作为空白窗口或容器
QMainWindowQtWidgets主窗口框架,包含菜单栏、工具栏、状态栏等
QDialogQtWidgets对话框基类,用于弹出窗口
布局管理QVBoxLayoutQtWidgets垂直布局管理器
QHBoxLayoutQtWidgets水平布局管理器
QGridLayoutQtWidgets网格布局管理器
QFormLayoutQtWidgets表单布局管理器(标签+输入框对)
按钮类QPushButtonQtWidgets普通按钮
QRadioButtonQtWidgets单选按钮
QCheckBoxQtWidgets复选框
QToolButtonQtWidgets工具栏按钮(可带图标)
输入控件QLineEditQtWidgets单行文本输入框
QTextEditQtWidgets多行富文本编辑器(支持html
QPlainTextEditQtWidgets多行纯文本编辑器
QSpinBoxQtWidgets数字调节框(整数)
QDoubleSpinBoxQtWidgets数字调节框(浮点数)
QComboBoxQtWidgets下拉选择框
QDateEditQtWidgets日期选择框
QTimeEditQtWidgets时间选择框
QDateTimeEditQtWidgets日期时间选择框
QSliderQtWidgets滑动条(水平/垂直)
QDialQtWidgets圆形旋钮控件
显示控件QLabelQtWidgets文本/图片标签
QLCDNumberQtWidgetsLCD数字显示屏
QProgressBarQtWidgets进度条
QStatusBarQtWidgets状态栏(通常用于QMainWindow)
容器类QGroupBoxQtWidgets分组框(带标题的容器)
QTabWidgetQtWidgets标签页容器
QStackedWidgetQtWidgets堆叠容器(每次显示一个子控件)
QScrollAreaQtWidgets滚动区域容器
QMdiAreaQtWidgetsMDI(多文档界面)区域
列表/表格/树QListWidgetQtWidgets列表控件(含项管理)
QTreeWidgetQtWidgets树形控件
QTableWidgetQtWidgets表格控件
QListViewQtWidgets列表视图(需搭配数据模型)
QTableViewQtWidgets表格视图(需搭配数据模型)
QTreeViewQtWidgets树形视图(需搭配数据模型)
菜单/工具栏QMenuBarQtWidgets菜单栏
QMenuQtWidgets菜单(可包含子菜单和动作)
QToolBarQtWidgets工具栏
QActionQtWidgets动作(用于菜单项、工具栏按钮等)
对话框QFileDialogQtWidgets文件选择对话框
QColorDialogQtWidgets颜色选择对话框
QFontDialogQtWidgets字体选择对话框
QInputDialogQtWidgets输入对话框(文本、数字等)
QMessageBoxQtWidgets消息提示框(警告、错误、询问等)
图形视图QGraphicsViewQtWidgets图形视图框架(用于2D图形)
QGraphicssceneQtWidgets图形场景(配合QGraphicsView使用)
其他功能组件QCalendarWidgetQtWidgets日历控件
QSplashScreenQtWidgets启动画面
QSystemTrayIconQtWidgets系统托盘图标
QWebEngineViewQtWebEngineWidgets网页浏览器组件(需单独安装PyQtWebEngine)

开发建议

  1. 学习资源:fly63 网站提供了详细的 PyQt 教程和实例代码

  2. 调试技巧:使用 print 语句输出调试信息,或者使用 Python 的调试工具

  3. 界面设计:先用 Qt Designer 设计界面,再添加业务逻辑

  4. 代码组织:将界面代码和业务逻辑分开,便于维护


总结

PyQt 是一个功能强大的图形界面开发工具。通过本教程,你学会了:

  • 创建基本的 PyQt 窗口

  • 使用各种界面组件

  • 管理布局

  • 处理用户交互

  • 制作完整的应用程序

PyQt 的学习曲线可能有些陡峭,但一旦掌握,你就能创建出专业的桌面应用程序。从简单的小工具开始,逐步尝试更复杂的项目,你会发现 PyQt 的强大之处。

记住,实践是最好的学习方法。多写代码,多尝试,你很快就能熟练使用 PyQt 了。

本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!

链接: https://fly63.com/course/36_2148

目录选择