PyQt 是 Python 中创建桌面应用程序的强大工具。它让你能够制作出专业外观的图形界面,就像我们日常使用的各种软件一样。无论你是想开发一个小工具,还是构建复杂的商业软件,PyQt 都能满足你的需求。
PyQt 是 Qt 框架的 Python 版本。Qt 本身是用 C++ 编写的跨平台应用程序框架,被很多知名软件使用,比如 Adobe Photoshop、Google Earth 等。PyQt 让 Python 开发者也能使用这个强大的框架。
PyQt5:基于 Qt5,目前使用最广泛的版本
PyQt6:基于 Qt6 的最新版本,推荐新项目使用
安装 PyQt 很简单,使用 pip 命令即可:
pip install PyQt6如果你需要可视化设计工具,还可以安装:
pip install PyQt6-Tools让我们从一个最简单的窗口开始:
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 程序包含以下几个部分:
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 提供了丰富的界面组件,让我们来看看最常用的一些。
标签用于显示文本或图片:
from PyQt6.QtWidgets import QLabel
from PyQt6.QtCore import Qt
label = QLabel("欢迎使用PyQt", self)
label.move(50, 50)
label.setAlignment(Qt.AlignmentFlag.AlignCenter) # 文字居中单行文本输入框:
from PyQt6.QtWidgets import QLineEdit
text_input = QLineEdit(self)
text_input.move(50, 100)
text_input.resize(200, 30)
text_input.setPlaceholderText("请输入用户名") # 提示文字按钮是最常用的交互组件:
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}")用于输入和显示多行文本:
from PyQt6.QtWidgets import QTextEdit
text_edit = QTextEdit(self)
text_edit.setGeometry(50, 200, 300, 150)
text_edit.setPlaceholderText("请输入内容...")手动设置每个组件的位置很麻烦,使用布局管理器可以自动排列组件。
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}")# 在垂直布局中添加水平布局
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
设计界面并保存为 .ui 文件
将 .ui 文件转换为 Python 代码
转换命令:
pyuic6 input.ui -o output.pyimport 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())这个记事本程序包含了文件操作、菜单栏、状态栏等完整功能。
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)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.QtWidgets。
高级功能(如多媒体、网络)可能需要其他模块(如 QtCore, QtGui, QtNetwork 等)。
QListView/QTableView/QTreeView 需要搭配数据模型(如 QStandardItemModel)使用,灵活性更高。
| 组件类别 | 组件名称 | 所在模块 | 说明 |
|---|---|---|---|
| 基础窗口组件 | QWidget | QtWidgets | 所有用户界面对象的基类,可作为空白窗口或容器 |
| QMainWindow | QtWidgets | 主窗口框架,包含菜单栏、工具栏、状态栏等 | |
| QDialog | QtWidgets | 对话框基类,用于弹出窗口 | |
| 布局管理 | QVBoxLayout | QtWidgets | 垂直布局管理器 |
| QHBoxLayout | QtWidgets | 水平布局管理器 | |
| QGridLayout | QtWidgets | 网格布局管理器 | |
| QFormLayout | QtWidgets | 表单布局管理器(标签+输入框对) | |
| 按钮类 | QPushButton | QtWidgets | 普通按钮 |
| QRadioButton | QtWidgets | 单选按钮 | |
| QCheckBox | QtWidgets | 复选框 | |
| QToolButton | QtWidgets | 工具栏按钮(可带图标) | |
| 输入控件 | QLineEdit | QtWidgets | 单行文本输入框 |
| QTextEdit | QtWidgets | 多行富文本编辑器(支持html) | |
| QPlainTextEdit | QtWidgets | 多行纯文本编辑器 | |
| QSpinBox | QtWidgets | 数字调节框(整数) | |
| QDoubleSpinBox | QtWidgets | 数字调节框(浮点数) | |
| QComboBox | QtWidgets | 下拉选择框 | |
| QDateEdit | QtWidgets | 日期选择框 | |
| QTimeEdit | QtWidgets | 时间选择框 | |
| QDateTimeEdit | QtWidgets | 日期时间选择框 | |
| QSlider | QtWidgets | 滑动条(水平/垂直) | |
| QDial | QtWidgets | 圆形旋钮控件 | |
| 显示控件 | QLabel | QtWidgets | 文本/图片标签 |
| QLCDNumber | QtWidgets | LCD数字显示屏 | |
| QProgressBar | QtWidgets | 进度条 | |
| QStatusBar | QtWidgets | 状态栏(通常用于QMainWindow) | |
| 容器类 | QGroupBox | QtWidgets | 分组框(带标题的容器) |
| QTabWidget | QtWidgets | 标签页容器 | |
| QStackedWidget | QtWidgets | 堆叠容器(每次显示一个子控件) | |
| QScrollArea | QtWidgets | 滚动区域容器 | |
| QMdiArea | QtWidgets | MDI(多文档界面)区域 | |
| 列表/表格/树 | QListWidget | QtWidgets | 列表控件(含项管理) |
| QTreeWidget | QtWidgets | 树形控件 | |
| QTableWidget | QtWidgets | 表格控件 | |
| QListView | QtWidgets | 列表视图(需搭配数据模型) | |
| QTableView | QtWidgets | 表格视图(需搭配数据模型) | |
| QTreeView | QtWidgets | 树形视图(需搭配数据模型) | |
| 菜单/工具栏 | QMenuBar | QtWidgets | 菜单栏 |
| QMenu | QtWidgets | 菜单(可包含子菜单和动作) | |
| QToolBar | QtWidgets | 工具栏 | |
| QAction | QtWidgets | 动作(用于菜单项、工具栏按钮等) | |
| 对话框 | QFileDialog | QtWidgets | 文件选择对话框 |
| QColorDialog | QtWidgets | 颜色选择对话框 | |
| QFontDialog | QtWidgets | 字体选择对话框 | |
| QInputDialog | QtWidgets | 输入对话框(文本、数字等) | |
| QMessageBox | QtWidgets | 消息提示框(警告、错误、询问等) | |
| 图形视图 | QGraphicsView | QtWidgets | 图形视图框架(用于2D图形) |
| QGraphicsscene | QtWidgets | 图形场景(配合QGraphicsView使用) | |
| 其他功能组件 | QCalendarWidget | QtWidgets | 日历控件 |
| QSplashScreen | QtWidgets | 启动画面 | |
| QSystemTrayIcon | QtWidgets | 系统托盘图标 | |
| QWebEngineView | QtWebEngineWidgets | 网页浏览器组件(需单独安装PyQtWebEngine) |
调试技巧:使用 print 语句输出调试信息,或者使用 Python 的调试工具
界面设计:先用 Qt Designer 设计界面,再添加业务逻辑
代码组织:将界面代码和业务逻辑分开,便于维护
PyQt 是一个功能强大的图形界面开发工具。通过本教程,你学会了:
创建基本的 PyQt 窗口
使用各种界面组件
管理布局
处理用户交互
制作完整的应用程序
PyQt 的学习曲线可能有些陡峭,但一旦掌握,你就能创建出专业的桌面应用程序。从简单的小工具开始,逐步尝试更复杂的项目,你会发现 PyQt 的强大之处。
记住,实践是最好的学习方法。多写代码,多尝试,你很快就能熟练使用 PyQt 了。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!