PySide6 入门指南--从零开始构建 Python GUI 应用
PySide6 是 Qt 库的 Python 绑定,允许开发者使用 Python 创建跨平台的图形用户界面(GUI)应用程序它是 Qt for Python 项目的一部分,由 Qt 官方维护
主要特点
跨平台支持:支持 Windows、macOS、Linux 等操作系统
丰富的组件库:提供按钮、文本框、表格、树形视图等多种 UI 组件
信号与槽机制:用于对象间通信,简化事件处理
国际化支持:便于开发多语言应用
开源:遵循 LGPL 许可,允许自由使用和修改
相关网址:
安装
pip install PySide6
安装完毕后,使用pyside6-designer
命令打开Qt Designerpyside6在安装时会自动安装Qt Designer
QuickStart
from PySide6.QtWidgets import QApplication, QWidget, QLabel
# 初始化PySide6应用程序
app = QApplication()
# 创建窗体
windows = QWidget()
windows.setWindowTitle("Hello Pyside6") # 设定窗体标题
windows.setFixedSize(500, 500) # 设定窗体大小(固定大小)
# 增加元素
lable = QLabel("Hello world", windows) # 创建标签
lable.move(250, 250) # 将标签位置到窗体250, 250的位置
# 显示窗体
windows.show()
# 启动应用程序的事件循环,等待事件的触发和处理,使窗体保持可响应状态
app.exec()
qtdesiner基本的使用
一下简略介绍qtdesiner基础使用
大概流程为File -> New -> Main Window -> Create -> 在组件框中拖选组件进入主窗口 -> 修改组件名字 -> 保存为.ui文件
更详细的操作可查看该网址:Qt Designer的简单使用 (biancheng.net)
主要功能
功能框内可以拖选文本框,标签等等放入到主窗口中,并且可以随意调节大小。
注意右边,该页面是作者调节过的,在Object Inspector页面中可以修改主界面中各组件的名字,选择某组件会在主界面中高亮
Property Editor可以调节该组件的参数
阅读代码/预览效果
可在以下操作中预览和浏览代码
布局管理器
QHBoxLayout(水平布局)
将控件按水平方向依次排列(从左到右)。适用于工具栏、一行按钮或标签
核心方法:
addWidget(widget)
:添加控件addLayout(layout)
:嵌套其他布局
from PySide6.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton
# 初始化PySide6应用程序
app = QApplication()
# 创建窗体
windows = QWidget()
windows.setWindowTitle("Hello Pyside6") # 设定窗体标题
windows.setFixedSize(500, 500) # 设定窗体大小(固定大小)
layout = QHBoxLayout()
# 添加按钮
btn1 = QPushButton("按钮1")
btn2 = QPushButton("按钮2")
btn3 = QPushButton("按钮3")
layout.addWidget(btn1)
layout.addWidget(btn2)
layout.addWidget(btn3)
# 设置布局到窗口
windows.setLayout(layout)
windows.setWindowTitle("水平布局示例")
# 显示窗体
windows.show()
# 启动应用程序的事件循环,等待事件的触发和处理,使窗体保持可响应状态
app.exec()
该布局也可以设置间距:
setSpacing(spacing)
:设置控件之间的间距setContentsMargins(left, top, right, bottom)
:设置布局边距
layout.setSpacing(10) # 控件间距为 10px
layout.setContentsMargins(20, 20, 20, 20) # 边距为 20px
QVBoxLayout(垂直布局)
将控件按垂直方向依次排列(从上到下)。适用于设置界面、表单布局
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
# 初始化PySide6应用程序
app = QApplication()
# 创建窗体
windows = QWidget()
windows.setWindowTitle("Hello Pyside6") # 设定窗体标题
windows.setFixedSize(500, 500) # 设定窗体大小(固定大小)
layout = QVBoxLayout()
# 添加按钮
btn1 = QPushButton("按钮1")
btn2 = QPushButton("按钮2")
btn3 = QPushButton("按钮3")
layout.addWidget(btn1)
layout.addWidget(btn2)
layout.addWidget(btn3)
# 设置布局到窗口
windows.setLayout(layout)
windows.setWindowTitle("垂直布局示例")
# 显示窗体
windows.show()
# 启动应用程序的事件循环,等待事件的触发和处理,使窗体保持可响应状态
app.exec()
QGridLayout(网格布局)
将控件按行和列排列成网格。适用于复杂表单、棋盘式布局
核心方法:
addWidget(widget, row, column)
:将控件添加到指定行列addWidget(widget, row, column, rowSpan, columnSpan)
:跨多行/列
from PySide6.QtWidgets import QApplication, QWidget, QGridLayout, QLabel, QLineEdit, QPushButton
# 初始化PySide6应用程序
app = QApplication()
# 创建窗体
windows = QWidget()
windows.setWindowTitle("Hello Pyside6") # 设定窗体标题
windows.setFixedSize(500, 500) # 设定窗体大小(固定大小)
layout = QGridLayout()
# 第0行
layout.addWidget(QLabel("用户名:"), 0, 0)
layout.addWidget(QLineEdit(), 0, 1)
# 第1行
layout.addWidget(QLabel("密码:"), 1, 0)
layout.addWidget(QLineEdit(), 1, 1)
# 第2行,跨两列
btn = QPushButton("登录")
layout.addWidget(btn, 2, 0, 1, 2) # 从第2行第0列开始,占1行2列
# 设置布局到窗口
windows.setLayout(layout)
windows.setWindowTitle("网格布局示例")
# 显示窗体
windows.show()
# 启动应用程序的事件循环,等待事件的触发和处理,使窗体保持可响应状态
app.exec()
QFormLayout(表单布局)
专门用于标签-输入框对的布局(类似 HTML 表单)。适用于登录界面、设置表单
核心方法:
addRow(label, widget)
:添加一行,左侧为标签,右侧为控件addRow(widget)
:添加一个占据整行的控件(如按钮)
from PySide6.QtWidgets import QApplication, QWidget, QFormLayout, QLineEdit, QPushButton
# 初始化PySide6应用程序
app = QApplication()
# 创建窗体
windows = QWidget()
windows.setWindowTitle("Hello Pyside6") # 设定窗体标题
windows.setFixedSize(500, 500) # 设定窗体大小(固定大小)
layout = QFormLayout()
# 添加标签和输入框
layout.addRow("用户名:", QLineEdit())
layout.addRow("密码:", QLineEdit())
# 添加一个整行按钮
btn = QPushButton("登录")
layout.addRow(btn)
# 设置布局到窗口
windows.setLayout(layout)
windows.setWindowTitle("表单布局示例")
# 显示窗体
windows.show()
# 启动应用程序的事件循环,等待事件的触发和处理,使窗体保持可响应状态
app.exec()
嵌套布局(组合使用)
将多种布局组合使用,创建复杂界面
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QGridLayout, QPushButton, QLabel
# 初始化PySide6应用程序
app = QApplication()
# 创建窗体
windows = QWidget()
windows.setWindowTitle("Hello Pyside6") # 设定窗体标题
windows.setFixedSize(500, 500) # 设定窗体大小(固定大小)
main_layout = QVBoxLayout()
# 顶部水平布局
top_layout = QHBoxLayout()
top_layout.addWidget(QPushButton("文件"))
top_layout.addWidget(QPushButton("编辑"))
main_layout.addLayout(top_layout)
# 中部网格布局
grid_layout = QGridLayout()
grid_layout.addWidget(QLabel("内容区域"), 0, 0)
main_layout.addLayout(grid_layout)
# 底部水平布局
bottom_layout = QHBoxLayout()
bottom_layout.addWidget(QPushButton("确定"))
bottom_layout.addWidget(QPushButton("取消"))
main_layout.addLayout(bottom_layout)
# 设置布局到窗口
windows.setLayout(main_layout)
windows.setWindowTitle("嵌套布局示例")
# 显示窗体
windows.show()
# 启动应用程序的事件循环,等待事件的触发和处理,使窗体保持可响应状态
app.exec()
布局的通用设置
拉伸因子(Stretch Factor)
控制控件在布局中的扩展比例
下面是一个简单的示例,演示如何让按钮占据剩余空间:
layout.addWidget(btn1, stretch=1) # 按钮1占1份
layout.addWidget(btn2, stretch=2) # 按钮2占2份
对齐方式(Alignment)
设置控件在布局中的对齐方式
layout.addWidget(label, alignment=Qt.AlignCenter) # 居中对齐
移除控件
从布局中移除控件
layout.removeWidget(widget)
窗口组件(Windows)
QMainWindow
QMainWindow 是专为应用程序主窗口设计的类,包含菜单栏、工具栏、状态栏和中心控件区域适合构建功能复杂的桌面应用(如文本编辑器、IDE)它的核心结构为:
菜单栏 (menuBar)
工具栏 (addToolBar)
状态栏 (statusBar)
中心部件 (setCentralWidget)
这是一个简单的代码示例:
from PySide6.QtWidgets import QApplication, QMainWindow, QTextEdit
# 初始化PySide6应用程序
app = QApplication()
# 创建主窗体
windows = QMainWindow()
windows.setWindowTitle("Hello Pyside6") # 设定窗体标题
windows.setFixedSize(500, 500) # 设定窗体大小(固定大小)
# 1. 创建菜单栏
menu_bar = windows.menuBar()
file_menu = menu_bar.addMenu("文件")
edit_menu = menu_bar.addMenu("编辑")
# 2. 创建状态栏
status_bar = windows.statusBar()
status_bar.showMessage("就绪")
# 3. 设置中心部件(例如一个文本编辑器)
text_edit = QTextEdit()
windows.setCentralWidget(text_edit)
# 4. 添加工具栏
toolbar = windows.addToolBar("工具")
toolbar.addAction("保存")
# 显示窗体
windows.show()
# 启动应用程序的事件循环,等待事件的触发和处理,使窗体保持可响应状态
app.exec()
常用方法:
QWidget
QWidget 是所有用户界面对象的基类,可以理解为“空白画布”,用于创建窗口或作为其他控件的容器它提供了窗口的基本功能(如位置、大小、事件处理等)
QuickStart中的示例就是演示了如何创建一个QWidget窗口
常用方法:
QDialog
QDialog 用于创建对话框窗口(如确认框、文件选择框)它分为两种模式:
模态对话框:阻塞主窗口操作,直到对话框关闭(使用
exec()
显示)非模态对话框:允许同时操作主窗口(使用
show()
显示)
这是一个简单的示例:
from PySide6.QtWidgets import QApplication, QWidget, QLabel, QDialog
# 初始化PySide6应用程序
app = QApplication()
# 创建窗体
windows = QWidget()
windows.setWindowTitle("Hello Pyside6") # 设定窗体标题
windows.setFixedSize(500, 500) # 设定窗体大小(固定大小)
# 增加元素
lable = QLabel("Hello world", windows) # 创建标签
lable.move(250, 250) # 将标签位置到窗体250, 250的位置
# 设置QDialog
dialog = QDialog(windows) # 父窗口为 QWidget
dialog.setWindowTitle("这是一个对话框")
# 显示窗体
windows.show()
# 等待dialog的反馈
dialog.exec()
# 启动应用程序的事件循环,等待事件的触发和处理,使窗体保持可响应状态
app.exec()
常用方法
常用控件(Widgets)
按钮类控件
QPushButton(普通按钮)
点击触发操作某个操作
button = QPushButton("点击我")
button.clicked.connect(lambda: print("按钮被点击"))
button.setEnabled(False) # 禁用按钮
QRadioButton(单选按钮)
多选一(同一父容器内的单选按钮互斥)
radio1 = QRadioButton("选项1")
radio2 = QRadioButton("选项2")
radio1.toggled.connect(lambda: print("选中选项1" if radio1.isChecked() else ""))
QCheckBox(复选框)
多选多
checkbox = QCheckBox("同意协议")
checkbox.stateChanged.connect(lambda state: print("选中" if state else "取消"))
文本输入类控件
QLineEdit(单行输入框)
输入单行文本(如用户名、密码)
line_edit = QLineEdit()
line_edit.setPlaceholderText("请输入内容") # 提示文本
line_edit.textChanged.connect(lambda text: print(f"输入内容: {text}"))
line_edit.setEchoMode(QLineEdit.Password) # 密码模式
QTextEdit(多行富文本编辑器)
支持带格式的多行文本(如加粗、颜色)
text_edit = QTextEdit()
text_edit.setHtml("<b>加粗文本</b> <font color='red'>红色文字</font>")
QPlainTextEdit(多行纯文本编辑器)
仅支持纯文本,性能优于 QTextEdit
plain_text = QPlainTextEdit()
plain_text.insertPlainText("Hello PySide6")
显示类控件
QLabel(标签)
显示文本或图片
label = QLabel("静态文本")
label.setPixmap(QPixmap("image.png")) # 显示图片
label.setAlignment(Qt.AlignCenter) # 居中显示
QLCDNumber(数字显示屏)
显示数字(类似计算器)
lcd = QLCDNumber()
lcd.display(123) # 显示数字
列表与下拉框
QListWidget(列表控件)
显示可交互的列表项
list_widget = QListWidget()
list_widget.addItems(["Item 1", "Item 2"])
list_widget.itemClicked.connect(lambda item: print(f"选中: {item.text()}"))
QComboBox(下拉选择框)
下拉选择一项
combo = QComboBox()
combo.addItems(["选项1", "选项2"])
combo.currentTextChanged.connect(lambda text: print(f"当前选项: {text}"))
进度与滑块
QProgressBar(进度条)
显示任务进度
progress = QProgressBar()
progress.setRange(0, 100) # 设置范围
progress.setValue(50) # 当前进度
QSlider(滑动条)
通过滑块选择数值(水平或垂直)
slider = QSlider(Qt.Horizontal) # 水平滑块
slider.setRange(0, 100)
slider.valueChanged.connect(lambda value: print(f"当前值: {value}"))
容器类控件
QGroupBox(分组框)
将控件分组并添加标题
group = QGroupBox("设置")
layout = QVBoxLayout()
layout.addWidget(QCheckBox("选项1"))
group.setLayout(layout)
QTabWidget(标签页容器)
通过标签页切换不同内容
tab_widget = QTabWidget()
tab1 = QWidget()
tab2 = QWidget()
tab_widget.addTab(tab1, "标签1")
tab_widget.addTab(tab2, "标签2")
QStackedWidget(堆叠容器)
同一区域切换不同页面(类似 QTabWidget
,但无标签)
stacked = QStackedWidget()
page1 = QWidget()
page2 = QWidget()
stacked.addWidget(page1)
stacked.addWidget(page2)
stacked.setCurrentIndex(1) # 切换到第二页
日期与时间
QDateEdit(日期选择)
选择日期
date_edit = QDateEdit()
date_edit.setDate(QDate.currentDate()) # 设置当前日期
date_edit.dateChanged.connect(lambda date: print(date.toString()))
QTimeEdit(时间选择)
选择时间
time_edit = QTimeEdit()
time_edit.setTime(QTime.currentTime())
高级控件
QTableView(表格视图)
显示表格数据,需配合数据模型(如 QStandardItemModel
)
model = QStandardItemModel()
model.setHorizontalHeaderLabels(["姓名", "年龄"])
model.appendRow([QStandardItem("张三"), QStandardItem("25")])
table_view = QTableView()
table_view.setModel(model)
QWebEngineView(网页视图)
嵌入网页内容(需安装 PySide6-QtWebEngine
)
pip install PySide6-QtWebEngine
以下是代码示例
web_view = QWebEngineView()
web_view.load("https://www.python.org")
文件与对话框(File Dialogs)
QFileDialog(文件对话框)
打开/保存文件、选择目录。
from PySide6.QtWidgets import QFileDialog
# 打开单个文件
file_path, _ = QFileDialog.getOpenFileName(None, "选择文件", "", "文本文件 (*.txt)")
# 保存文件
save_path, _ = QFileDialog.getSaveFileName(None, "保存文件", "", "图片 (*.png)")
# 选择目录
dir_path = QFileDialog.getExistingDirectory(None, "选择目录")
QMessageBox(消息框)
显示提示、警告、确认对话框。
from PySide6.QtWidgets import QMessageBox
# 信息提示框
QMessageBox.information(None, "提示", "操作成功!")
# 确认对话框
result = QMessageBox.question(None, "确认", "确定删除吗?")
if result == QMessageBox.Yes:
print("用户确认删除")
信号与槽(Signals & Slots)
信号(Signal):由对象发出的通知(如按钮点击、文本修改)
槽(Slot):接收信号并执行操作的函数
它们组合在一起实现组件间通信和事件响应
from PySide6.QtWidgets import QPushButton, QApplication
def on_button_click():
print("按钮被点击")
app = QApplication([])
button = QPushButton("点击我")
# 连接信号与槽
button.clicked.connect(on_button_click)
button.show()
app.exec()
自定义信号:
from PySide6.QtCore import QObject, Signal
class MyEmitter(QObject):
# 定义一个信号,参数为字符串
my_signal = Signal(str)
emitter = MyEmitter()
# 定义槽函数
def handle_signal(text):
print(f"收到信号: {text}")
# 连接信号与槽
emitter.my_signal.connect(handle_signal)
# 发射信号
emitter.my_signal.emit("Hello PySide6")
多线程(Multithreading)
QThread(线程类)
防止耗时任务阻塞主线程(避免界面卡死)。
from PySide6.QtCore import QThread, Signal
class WorkerThread(QThread):
# 定义信号,传递进度值
progress_updated = Signal(int)
def run(self):
for i in range(1, 101):
self.msleep(50) # 模拟耗时操作
self.progress_updated.emit(i)
# 在主线程中使用
worker = WorkerThread()
worker.progress_updated.connect(lambda value: print(f"进度: {value}%"))
worker.start() # 启动线程