Python GUI Pyside6 实例笔记
例【1】
好的!我们将通过一个简单的案例来学习如何使用 PySide6 创建一个基本的桌面应用程序。这个案例将展示如何创建一个带有按钮的窗口,当点击按钮时,会弹出一个消息框。
1. 安装 PySide6
首先,确保你已经安装了 PySide6。如果没有安装,可以使用以下命令进行安装:
pip install PySide6
2. 创建一个简单的窗口
我们将创建一个简单的窗口,窗口中包含一个按钮。当用户点击按钮时,会弹出一个消息框。
import sys
from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox
class MyWindow(QWidget):
def __init__(self):
super().__init__()
# 设置窗口标题
self.setWindowTitle("PySide6 示例")
# 设置窗口大小
self.resize(300, 200)
# 创建一个按钮
self.button = QPushButton("点击我", self)
self.button.clicked.connect(self.show_message)
# 设置按钮的位置和大小
self.button.setGeometry(100, 80, 100, 40)
def show_message(self):
# 创建一个消息框
QMessageBox.information(self, "消息", "你点击了按钮!")
if __name__ == "__main__":
# 创建应用程序对象
app = QApplication(sys.argv)
# 创建窗口对象
window = MyWindow()
# 显示窗口
window.show()
# 进入应用程序的主循环
sys.exit(app.exec())
3. 代码解释
QApplication
对象。MyWindow
继承自 QWidget
。QMessageBox.information
来显示一个消息框。clicked
信号连接到 show_message
槽函数。当按钮被点击时,show_message
函数会被调用。4. 运行代码
将上述代码保存为一个 Python 文件(例如 main.py
),然后在终端中运行:
python main.py
你将看到一个带有按钮的窗口。当你点击按钮时,会弹出一个消息框,显示“你点击了按钮!”。
5. 进一步学习
通过这个简单的案例,你已经学会了如何使用 PySide6 创建一个基本的桌面应用程序。接下来,你可以尝试添加更多的控件(如文本框、标签等),并学习如何处理用户输入、布局管理、信号与槽机制等更高级的功能。
例【2】
好的!接下来我们通过第二个例子来进一步学习 PySide6。这个例子将展示如何使用 布局管理器 和 多个控件 来创建一个更复杂的用户界面。
我们将创建一个简单的表单应用程序,包含以下功能:
- 一个输入框用于输入用户名。
- 一个输入框用于输入密码。
- 一个登录按钮,点击后检查用户名和密码是否正确。
- 一个标签用于显示登录结果。
示例代码
代码解释
- 布局管理器 (
QVBoxLayout
):
QVBoxLayout
垂直布局管理器来排列控件。- 控件:
QLabel
: 用于显示文本标签。QLineEdit
: 用于输入文本。我们为密码输入框设置了 setEchoMode(QLineEdit.Password)
,使输入内容显示为星号。QPushButton
: 用于触发登录操作。- 信号与槽:
button_login.clicked.connect(self.check_login)
会将点击事件连接到 check_login
方法。- 登录逻辑:
check_login
方法中,我们检查输入的用户名和密码是否正确。admin
且密码是 123456
,则显示登录成功的消息;否则显示登录失败的消息。- 消息框 (
QMessageBox
):
QMessageBox.information
显示成功消息。QMessageBox.warning
显示失败消息。运行代码
将上述代码保存为 login_form.py
,然后在终端中运行:
python login_form.py
你会看到一个登录表单窗口,输入用户名和密码后点击登录按钮,程序会检查输入是否正确并显示相应的消息。
进一步学习
通过这个例子,你已经学会了:
QVBoxLayout
) 来排列控件。QLineEdit
和 QPushButton
等控件。接下来,你可以尝试:
- 添加更多的输入字段(如邮箱、电话号码)。
- 使用其他布局管理器(如
QHBoxLayout
或QGridLayout
)。 - 将数据保存到文件或数据库中。
😊
例【3】
好的!接下来我们通过第三个例子来学习如何使用 PySide6 创建一个带有菜单栏、工具栏和状态栏的完整桌面应用程序。这个例子将展示如何构建一个更复杂的用户界面,并实现一些常见的功能。
示例:文本编辑器
我们将创建一个简单的文本编辑器,包含以下功能:
- 菜单栏:包含“文件”菜单,支持打开、保存和退出操作。
- 工具栏:包含“打开”和“保存”按钮。
- 状态栏:显示当前文件的状态。
- 文本编辑区域:用于编辑文本内容。
示例代码
代码解释
- QMainWindow:
QMainWindow
是主窗口类,提供了菜单栏、工具栏、状态栏和中心部件的支持。- 菜单栏 (
QMenuBar
):
menuBar()
创建菜单栏。- 工具栏 (
QToolBar
):
QToolBar
创建工具栏。- 状态栏 (
QStatusBar
):
QStatusBar
创建状态栏,用于显示当前文件的状态。- 文本编辑区域 (
QTextEdit
):
QTextEdit
作为中心部件,用于编辑文本内容。- 文件操作:
open_file
: 打开文件并加载内容到文本编辑区域。save_file
: 保存文本编辑区域的内容到文件。- 图标:
QIcon
为动作添加图标(需要准备图标文件,如 open.png
和 save.png
)。运行代码
将上述代码保存为 text_editor.py
,然后在终端中运行:
python text_editor.py
你会看到一个简单的文本编辑器窗口,支持打开、保存文本文件,并显示状态信息。
进一步学习
通过这个例子,你已经学会了:
QMainWindow
创建主窗口。接下来,你可以尝试:
- 添加更多功能,如“另存为”、“撤销”、“重做”等。
- 支持更多文件格式(如 Markdown、HTML)。
- 添加快捷键支持(如 Ctrl+O 打开文件)。
😊
例【4】
好的!接下来我们通过第四个例子来学习如何使用 PySide6 创建一个带有 表格控件 和 数据操作 的应用程序。这个例子将展示如何使用 QTableWidget
来显示和编辑表格数据,并实现数据的增删改查功能。
示例:学生信息管理系统
我们将创建一个简单的学生信息管理系统,包含以下功能:
- 表格显示:使用
QTableWidget
显示学生信息(姓名、年龄、成绩)。 - 添加数据:通过对话框添加新的学生信息。
- 删除数据:删除选中的学生信息。
- 编辑数据:双击表格单元格编辑学生信息。
- 保存和加载数据:将数据保存到文件并从文件加载数据。
示例代码
代码解释
- QTableWidget:
["姓名", "年龄", "成绩"]
。- 添加数据:
QInputDialog
弹出输入对话框,获取学生信息。- 删除数据:
- 保存数据:
- 加载数据:
- 菜单栏和状态栏:
运行代码
将上述代码保存为 student_manager.py
,然后在终端中运行:
python student_manager.py
你会看到一个学生信息管理系统窗口,支持添加、删除、编辑学生信息,并可以将数据保存到文件或从文件加载数据。
进一步学习
通过这个例子,你已经学会了:
QTableWidget
显示和编辑表格数据。接下来,你可以尝试:
- 添加更多字段(如性别、班级)。
- 实现数据排序和过滤功能。
- 使用数据库(如 SQLite)存储数据。
😊
例【5】
好的!接下来我们通过第五个例子来学习如何使用 PySide6 创建一个带有 图形绘制功能 的应用程序。这个例子将展示如何使用 QPainter
在窗口中绘制简单的图形(如线条、矩形、圆形等),并支持用户交互(如鼠标点击绘制点)。
示例:简单绘图工具
我们将创建一个简单的绘图工具,包含以下功能:
- 绘制图形:支持绘制线条、矩形、圆形。
- 选择颜色:通过颜色对话框选择绘图颜色。
- 清空画布:清除所有绘制的图形。
- 保存绘图:将绘图保存为图片文件。
示例代码
代码解释
- DrawingWidget:
QWidget
,用于处理绘图逻辑。QPainter
在 paintEvent
中绘制图形。- 绘图模式:
drawing_mode
属性切换绘图模式。- 颜色选择:
QColorDialog
选择绘图颜色。- 清空画布:
- 保存绘图:
QImage
将绘图保存为图片文件(PNG 或 JPEG)。- 主窗口:
运行代码
将上述代码保存为 drawing_tool.py
,然后在终端中运行:
python drawing_tool.py
你会看到一个简单的绘图工具窗口,支持绘制线条、矩形和圆形,并可以保存绘图为图片。
进一步学习
通过这个例子,你已经学会了:
QPainter
绘制图形。接下来,你可以尝试:
- 添加更多绘图工具(如画笔、橡皮擦)。
- 支持撤销和重做功能。
- 实现更复杂的图形(如多边形、曲线)。
😊
例【6】
好的!接下来我们通过第六个例子来学习如何使用 PySide6 创建一个带有 多线程 的应用程序。这个例子将展示如何在 GUI 应用程序中使用多线程来执行耗时任务,避免界面卡顿。
示例:多线程任务执行器
我们将创建一个简单的任务执行器,包含以下功能:
- 任务执行:在后台线程中执行耗时任务。
- 进度更新:在主线程中更新任务进度。
- 任务取消:支持取消正在执行的任务。
- 任务完成通知:任务完成后弹出提示。
示例代码
代码解释
- WorkerThread:
QThread
,用于在后台执行耗时任务。update_progress
信号更新任务进度。task_finished
信号通知任务完成。- TaskExecutor:
WorkerThread
执行任务,并通过信号更新 UI。- 信号与槽:
update_progress
:用于更新进度条。task_finished
:用于任务完成后的处理。- 任务取消:
QMutex
实现线程安全的任务取消功能。- UI 更新:
运行代码
将上述代码保存为 task_executor.py
,然后在终端中运行:
python task_executor.py
你会看到一个任务执行器窗口,点击“开始任务”按钮后,进度条会逐渐更新。你可以随时点击“取消任务”按钮停止任务。
进一步学习
通过这个例子,你已经学会了:
QThread
在后台执行耗时任务。接下来,你可以尝试:
- 添加更多任务类型(如文件下载、数据处理)。
- 实现任务队列,支持多个任务依次执行。
- 使用线程池 (
QThreadPool
) 管理多个线程。
😊
例【7】
好的!接下来我们通过第七个例子来学习如何使用 PySide6 创建一个带有 网络请求功能 的应用程序。这个例子将展示如何使用 QNetworkAccessManager
发送 HTTP 请求并处理响应,同时结合 GUI 实现一个简单的天气查询工具。
示例:简单天气查询工具
我们将创建一个简单的天气查询工具,包含以下功能:
- 输入城市名称:用户输入城市名称。
- 发送网络请求:使用
QNetworkAccessManager
发送 HTTP 请求到天气 API。 - 显示天气信息:解析 API 返回的 JSON 数据并显示天气信息。
- 错误处理:处理网络请求失败的情况。
示例代码
代码解释
- QNetworkAccessManager:
get
方法发送 GET 请求。- QNetworkRequest:
- QNetworkReply:
finished
信号连接槽函数 handle_response
。- JSON 解析:
json
模块解析 API 返回的 JSON 数据。- 错误处理:
reply.error()
是否为 QNetworkReply.NoError
。- UI 组件:
QLineEdit
:用于输入城市名称。QPushButton
:用于触发查询操作。QTextEdit
:用于显示查询结果。运行代码
- 将上述代码保存为
weather_app.py
。 - 替换
api_key
为你的天气 API 密钥(可以从 OpenWeatherMap 获取)。 - 在终端中运行:
python weather_app.py
你会看到一个天气查询工具窗口,输入城市名称后点击“查询天气”按钮,程序会显示该城市的天气信息。
进一步学习
通过这个例子,你已经学会了:
QNetworkAccessManager
发送 HTTP 请求。接下来,你可以尝试:
- 添加更多天气信息(如湿度、风速)。
- 支持多城市查询。
- 使用其他 API(如新闻 API、地图 API)。
😊
例【8】
好的!接下来我们通过第八个例子来学习如何使用 PySide6 创建一个带有 数据库功能 的应用程序。这个例子将展示如何使用 SQLite 数据库存储和检索数据,并结合 GUI 实现一个简单的联系人管理系统。
示例:联系人管理系统
我们将创建一个简单的联系人管理系统,包含以下功能:
- 添加联系人:输入姓名和电话号码,保存到数据库。
- 显示联系人:从数据库中加载联系人并显示在表格中。
- 删除联系人:删除选中的联系人。
- 搜索联系人:根据姓名搜索联系人。
示例代码
代码解释
- SQLite 数据库:
sqlite3
模块创建和管理 SQLite 数据库。contacts
表存储联系人信息。- QTableWidget:
- 添加联系人:
- 删除联系人:
- 搜索联系人:
LIKE
语句实现模糊搜索。- 关闭事件:
运行代码
- 将上述代码保存为
contact_manager.py
。 - 在终端中运行:
python contact_manager.py
你会看到一个联系人管理系统窗口,支持添加、删除和搜索联系人。
进一步学习
通过这个例子,你已经学会了:
接下来,你可以尝试:
- 添加更多字段(如邮箱、地址)。
- 实现联系人编辑功能。
- 使用其他数据库(如 MySQL、PostgreSQL)。
😊
例【9】
好的!接下来我们通过第九个例子来学习如何使用 PySide6 创建一个带有 图表绘制功能 的应用程序。这个例子将展示如何使用 QtCharts
模块绘制动态折线图,并结合 GUI 实现一个简单的实时数据监控工具。
示例:实时数据监控工具
我们将创建一个简单的实时数据监控工具,包含以下功能:
- 动态折线图:实时显示随机生成的数据。
- 开始/停止监控:控制数据的生成和显示。
- 清空图表:清除当前图表数据。
示例代码
代码解释
- QtCharts:
QChart
和 QLineSeries
创建折线图。QValueAxis
设置坐标轴范围和标题。- QTimer:
QTimer
定时生成数据并更新图表。- 动态数据更新:
- 按钮功能:
- UI 布局:
QVBoxLayout
垂直排列图表和按钮。运行代码
- 将上述代码保存为
real_time_monitor.py
。 - 在终端中运行:
python real_time_monitor.py
你会看到一个实时数据监控工具窗口,点击“开始监控”按钮后,图表会动态显示随机生成的数据。
进一步学习
通过这个例子,你已经学会了:
QtCharts
绘制动态折线图。QTimer
实现实时数据更新。接下来,你可以尝试:
- 添加更多数据系列(如多条折线)。
- 实现数据保存和加载功能。
- 使用其他图表类型(如柱状图、饼图)。
😊
例【10】
好的!接下来我们通过第十个例子来学习如何使用 PySide6 创建一个带有 多媒体功能 的应用程序。这个例子将展示如何使用 QMediaPlayer
和 QVideoWidget
实现一个简单的视频播放器。
示例:简单视频播放器
我们将创建一个简单的视频播放器,包含以下功能:
- 播放视频:加载并播放视频文件。
- 暂停/继续:暂停或继续播放视频。
- 音量控制:调整视频音量。
- 进度控制:拖动滑块调整播放进度。
示例代码
代码解释
- QMediaPlayer:
- QVideoWidget:
- QSlider:
- QFileDialog:
- 信号与槽:
positionChanged
:视频播放位置变化时更新进度滑块。durationChanged
:视频总时长变化时更新进度滑块范围。- 按钮功能:
运行代码
- 将上述代码保存为
video_player.py
。 - 在终端中运行:
python video_player.py
你会看到一个视频播放器窗口,点击“打开视频文件”按钮选择视频文件后,可以播放、暂停视频,并调整音量和播放进度。
进一步学习
通过这个例子,你已经学会了:
QMediaPlayer
和 QVideoWidget
播放视频。QFileDialog
选择文件。接下来,你可以尝试:
- 添加更多功能(如全屏播放、播放列表)。
- 支持更多视频格式。
- 实现字幕加载功能。
😊
例【11】
你的代码已经实现了一个功能丰富的 QTabBar
示例,支持动态添加、关闭和移动选项卡,并且通过样式表美化了界面。以下是代码的详细解释和一些改进建议:
代码解释
- 主窗口和布局:
QMainWindow
作为主窗口,并设置标题和初始大小。QVBoxLayout
作为主布局,包含一个 QHBoxLayout
用于放置 QTabBar
和添加按钮。- QTabBar:
QTabBar
创建选项卡栏。setFixedHeight(40)
)。setExpanding(False)
)。setUsesScrollButtons(True)
)。- 添加按钮:
QPushButton
创建添加按钮,点击后动态添加新选项卡。setStyleSheet
设置。- 选项卡功能:
add_new_tab
方法)。tabCloseRequested
信号)。tabMoved
信号)。currentChanged
信号)。- 样式表:
setStyleSheet
美化 QTabBar
和按钮。改进建议
- 固定第一个和最后一个选项卡的大小:
QTabBar
并重写 tabSizeHint
方法。- 选项卡内容管理:
QStackedWidget
来管理每个选项卡的内容。- 优化样式:
改进后的代码
以下是改进后的代码,结合了 QStackedWidget
来管理选项卡内容,并优化了样式:
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QTabBar, QPushButton, QHBoxLayout, QLabel, QStackedWidget
from PySide6.QtCore import Qt, QSize
class TabBarDemo(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("QTabBar 示例")
self.setGeometry(100, 100, 600, 400)
self.tab_count = 1 # 用于生成新标签页的计数器
# 创建中心部件和布局
central_widget = QWidget()
self.setCentralWidget(central_widget)
main_layout = QVBoxLayout(central_widget)
# 创建水平布局来放置TabBar和添加按钮
top_layout = QHBoxLayout()
# 创建 QTabBar
self.tab_bar = QTabBar()
# 设置标签页固定大小
self.tab_bar.setFixedHeight(40) # 设置标签栏高度
self.tab_bar.setExpanding(False) # 禁止标签自动扩展
self.tab_bar.setUsesScrollButtons(True) # 启用滚动按钮
top_layout.addWidget(self.tab_bar)
# 创建添加标签页的按钮
add_button = QPushButton("+")
add_button.setFixedSize(30, 25)
add_button.clicked.connect(self.add_new_tab)
top_layout.addWidget(add_button)
# 将水平布局添加到主布局
main_layout.addLayout(top_layout)
# 创建 QStackedWidget 来管理选项卡内容
self.stacked_widget = QStackedWidget()
main_layout.addWidget(self.stacked_widget)
# 添加初始选项卡
self.add_tab("首页", "这是首页内容")
self.add_tab("文档", "这是文档内容")
self.add_tab("设置", "这是设置内容")
self.add_tab("关于", "这是关于内容")
# 设置标签页可移动
self.tab_bar.setMovable(True)
# 设置标签页可关闭
self.tab_bar.setTabsClosable(True)
# 连接信号
self.tab_bar.currentChanged.connect(self.tab_changed)
self.tab_bar.tabCloseRequested.connect(self.close_tab)
self.tab_bar.tabMoved.connect(self.tab_moved)
# 添加一些样式
self.tab_bar.setStyleSheet("""
QTabBar::tab {
background: #f0f0f0;
border: 1px solid #c0c0c0;
padding: 8px 20px;
margin-right: 2px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
width: 120px; /* 设置标签固定宽度 */
max-width: 120px; /* 设置最大宽度 */
min-width: 120px; /* 设置最小宽度 */
}
QTabBar::tab:selected {
background: #e0e0e0;
border-bottom-color: #e0e0e0;
}
QTabBar::tab:hover {
background: #e5e5e5;
}
QTabBar::scroller {
width: 20px;
}
QTabBar QToolButton {
background: #f0f0f0;
border: 1px solid #c0c0c0;
border-radius: 4px;
}
QTabBar QToolButton:hover {
background: #e5e5e5;
}
""")
add_button.setStyleSheet("""
QPushButton {
background: #f0f0f0;
border: 1px solid #c0c0c0;
border-radius: 4px;
font-weight: bold;
}
QPushButton:hover {
background: #e5e5e5;
}
""")
def add_tab(self, name, content):
# 添加选项卡
index = self.tab_bar.addTab(name)
# 创建内容页面
page = QLabel(content)
page.setAlignment(Qt.AlignCenter)
self.stacked_widget.addWidget(page)
# 切换到新添加的选项卡
self.tab_bar.setCurrentIndex(index)
def add_new_tab(self):
new_tab_name = f"新标签页 {self.tab_count}"
self.add_tab(new_tab_name, f"这是 {new_tab_name} 的内容")
self.tab_count += 1
print(f"添加新标签页: {new_tab_name}")
def tab_changed(self, index):
# 切换选项卡时更新内容
self.stacked_widget.setCurrentIndex(index)
print(f"切换到标签页 {index}: {self.tab_bar.tabText(index)}")
def close_tab(self, index):
# 关闭选项卡时移除内容和标签
self.tab_bar.removeTab(index)
self.stacked_widget.removeWidget(self.stacked_widget.widget(index))
print(f"关闭标签页 {index}")
def tab_moved(self, _from, to):
# 移动选项卡时更新内容顺序
widget = self.stacked_widget.widget(_from)
self.stacked_widget.removeWidget(widget)
self.stacked_widget.insertWidget(to, widget)
print(f"标签页从位置 {_from} 移动到位置 {to}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = TabBarDemo()
window.show()
sys.exit(app.exec())
改进点
- 结合
QStackedWidget
:
QStackedWidget
管理每个选项卡的内容。QStackedWidget
的当前页面。- 动态添加和删除内容:
- 优化样式:
运行代码
- 将上述代码保存为
tabbar_demo.py
。 - 在终端中运行:
python tabbar_demo.py
你会看到一个功能丰富的选项卡管理器窗口,支持动态添加、关闭和移动选项卡,并且每个选项卡都有对应的内容。
进一步学习
通过这个例子,你已经学会了:
QTabBar
和 QStackedWidget
管理选项卡和内容。
😊
例【12】
PySide6移除窗口顶部栏
代码:
import sys
from PySide6.QtWidgets import QApplication, QWidget, QPushButton
from PySide6.QtCore import Qt, QPoint
class FramelessWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Frameless Window")
self.setGeometry(100, 100, 400, 300)
# 设置窗口标志,移除顶部栏
self.setWindowFlags(Qt.FramelessWindowHint)
# 用于窗口拖动的变量
self.dragging = False
self.offset = QPoint()
# 添加关闭按钮
self.close_button = QPushButton('X', self)
self.close_button.setGeometry(self.width() - 30, 0, 30, 30) # 设置按钮位置和大小
self.close_button.clicked.connect(self.close) # 连接关闭按钮的点击事件到关闭窗口的方法
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.dragging = True
self.offset = event.globalPosition().toPoint() - self.pos()
def mouseMoveEvent(self, event):
if self.dragging:
self.move(event.globalPosition().toPoint() - self.offset)
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.dragging = False
if __name__ == "__main__":
app = QApplication(sys.argv)
window = FramelessWindow()
window.show()
sys.exit(app.exec())
contine…
作者:PieroPc