PySide6入门
一、前言
随着桌面应用开发的需求不断增长,Python 作为一门简洁易学、生态丰富的语言,逐渐成为许多开发者构建图形界面的首选。而 Qt 框架作为功能强大、跨平台的 GUI 库,也自然成为 Python 社区的热门选择。
PySide6 是 Qt 官方提供的 Python 绑定库,又被称为 Qt for Python。它基于 Qt 6 版本,具备强大的跨平台能力和丰富的界面组件,可以帮助开发者快速构建现代化、功能完整的桌面应用程序。
与广为人知的 PyQt 相比,PySide6 的最大优势在于其开放的 LGPL 许可协议,这意味着开发者可以在闭源项目中免费使用它,而无需担心商业授权问题。
本文档积累作者从零开始学习 PySide6,从环境配置、基础控件使用,到信号槽机制、界面设计工具(Qt Designer),一步步掌握开发桌面应用的核心技能。
二、环境搭建
这里使用python 3.11 版本,推荐创建虚拟环境,这里我使用anaconda创建一个虚拟环境(使用python 3.11.11):
安装PySide6:
pip install PySide6
PySide6安装完成后,对应的工具也会安装完成,比如Qt Designer,我们可以在安装目录找到Qt Designer,看看能不能打开:
能打开说明安装的没有问题。
如果使用Vs Code开发,可以按照下面的步骤配置(PyCharm也可以)
安装插件:PYQT Integration
进行插件设置:
设置Qt Designer路径:
设置Pyrcc: Cmd路径:
设置Pyuic: Cmd路径:
测试:弹出Qt Designer就算配置好了。
三、第一个 PySide6 程序
from PySide6.QtWidgets import QApplication, QMainWindow
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
if __name__ == '__main__':
app = QApplication()
window = MainWindow()
window.show()
app.exec()
运行效果如下:
代码解释:
from PySide6.QtWidgets import QApplication, QMainWindow
从 PySide6.QtWidgets
模块导入两个常用的类:
QApplication
:整个 Qt 应用的核心类,必须有一个,管理事件循环。QMainWindow
:一个标准的主窗口类,带菜单栏、工具栏、状态栏的结构化窗口。
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
定义一个自己的主窗口类 MainWindow,继承自 QMainWindow。
super().__init__()
:调用父类的初始化方法,这是必须的,否则QMainWindow
功能不会初始化。
if __name__ == '__main__':
Python 的标准入口判断:
- 表示 只有直接运行这个文件时,才会执行下面的代码;
- 如果这个文件被当作模块导入,下面的代码不会执行。
app = QApplication()
创建一个 QApplication 实例,整个程序只能有一个 app。这个实例负责整个 GUI 程序的 事件循环、信号处理 等。
window = MainWindow()
window.show()
app.exec()
- 创建我们自定义的主窗口实例(就是前面那个 MainWindow 类)
- 把窗口显示出来!
- 启动 Qt 的事件循环(Event Loop)
四、常用控件
在 PySide6 中,Qt 提供了大量 UI 控件,用于构建各种类型的界面。本部分将介绍一些最常用的控件及其基本使用方法。
4.1 QPushButton - 按钮
点击后触发事件,常用于执行操作。
button = QPushButton("点击我")
button.clicked.connect(lambda: print("按钮被点击"))
4.2 QLabel - 标签
用于显示文本或图片。
label = QLabel("这是一个标签")
label.setText("支持动态修改文本")
4.3 QLineEdit - 单行文本输入框
用户可以输入文字,支持设置密码模式、限制字符等。
line_edit = QLineEdit()
line_edit.setPlaceholderText("请输入用户名")
line_edit.setEchoMode(QLineEdit.Password) # 密码模式
五、Qt Designer 可视化界面设计
Qt Designer使用
在文件区域右键可以选择打开Qt Designer:
打开后如下图:
UI文件转换
Qt Designer设计文件的后缀为.ui,我们可以使用命令将ui设计文件转换为oython代码,方便我们进一步修改:
使用命令:
pyside6-uic .\test.ui -o test.py
就可以将test.ui这个设计文件转换为test.py这个python代码。
也可以使用可视化界面:
UI文件导入
from PySide6.QtWidgets import QApplication, QMainWindow
from test import Ui_MainWindow
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == '__main__':
app = QApplication()
window = MainWindow()
window.show()
app.exec()
可以通过下面的代码显示我们绘制的UI
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
效果如下:
六、信号与槽机制
from PySide6.QtWidgets import QApplication, QWidget, QPushButton
class MainWindow(QWidget):
def __init__(self):
super().__init__()
button = QPushButton("按键",self)
button.clicked.connect(self.buttonClicked)
def buttonClicked(self):
print("按钮被点击")
if __name__ == '__main__':
app = QApplication()
window = MainWindow()
window.show()
七、子线程
多线程的子类化:
from PySide6.QtCore import QThread, Signal
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel
class WorkerThread(QThread):
signal = Signal(str)
def __init__(self):
super().__init__()
print("Worker")
def run(self):
for i in range(10):
self.signal.emit(str(i))
self.sleep(1)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.lb = QLabel("当前值为:0")
self.worker = WorkerThread()
self.worker.signal.connect(lambda x: self.lb.setText("当前值为:" + x))
self.worker.start()
self.mainLayut = QVBoxLayout()
self.mainLayut.addWidget(self.lb)
self.setLayout(self.mainLayut)
if __name__ == '__main__':
app = QApplication()
window = MainWindow()
window.show()
app.exec()
总结:
- 自定义信号
- 信号的手动触发
- 主线程创建子线程实例
- 主线程对子线程的信号进行绑定
- 开始子线程
多线程的实例化:
from PySide6.QtCore import QThread, Signal, QObject
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel
import time
class WorkerThread(QObject):
signal = Signal(str)
def __init__(self):
super().__init__()
print("Worker")
def run(self):
for i in range(10):
self.signal.emit(str(i))
time.sleep(1)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.lb = QLabel("当前值为:0")
self.worker = WorkerThread()
self.thread = QThread()
self.worker.moveToThread(self.thread)
self.worker.signal.connect(lambda x: self.lb.setText("当前值为:" + x))
self.thread.started.connect(self.worker.run)
self.thread.start()
self.mainLayut = QVBoxLayout()
self.mainLayut.addWidget(self.lb)
self.setLayout(self.mainLayut)
if __name__ == '__main__':
app = QApplication()
window = MainWindow()
window.show()
app.exec()
参考
- https://pypi.org/project/PySide6/
- https://www.bilibili.com/video/BV1c84y1N7iL
- https://www.pythonguis.com/pyside6/
相关资源:
样式美化库
项目模板:
https://github.com/Wanderson-Magalhaes/Modern_GUI_PyDracula_PySide6_or_PyQt6