我们已经实现了表格的展示功能。接下来,我们将实现新增学生信息的功能,点击新增按钮通过一个弹出框来填写学生信息并保存到数据库。如下图所示:
添加学生信息分析与设计
在实现前,我们先分析一下添加学生信息和编辑学生信息的相似之处。经过对比,这两个功能的界面是完全相同的,区别在于“添加”时表单为空,而“编辑”时表单填充了已有的数据。如下图所示:
在开发过程中,为了简化代码并提高复用性,我们可以通过创建一个GUI基类来实现相同功能的不同窗口逻辑复用。具体而言,可以为添加和修改操作分别创建类,这些类继承自同一个基类或父类,从而实现代码的复用与维护上的便利性。
学生管理基类实现
在学生管理的场景中,我们可以创建一个基类,针对“添加”操作实现空表单,针对“修改”操作从数据库中获取当前用户信息并填充表单。首先,我们在student模块中创建一个新文件,命名为student_dialog。目录结构如下图所示:
在这里,我们以Fluent UI中提供的弹窗效果为参考,使用类似的样式进行实现。在Fluent UI的文档中,可以找到一个名为dialog_flyout/custom_message_box文件夹下的自定义弹窗示例,其弹窗效果包含输入框,这个自定义弹窗类继承是MessageBoxBase这个父类,我们将基于这个示例编写自己的窗口样式,如下图所示:
接下来我们在student/student_dialog.py文件中创建一个名为BaseStudentDialog的类,并让它继承自MessageBoxBase。需要对MessageBoxBase模块进行必要的导入。 在类中定义初始化方法__init__,接收title和parent两个参数,默认parent=None。通过调用父类的初始化方法,完成基础设置。此外,title参数用于区分窗口的用途,例如“添加学生信息”或“修改学生信息”,代码如下:
# student/student_dialog.py 文件中
from qfluentwidgets import MessageBoxBase # 导入 qfluentwidgets 模块中的 MessageBoxBase 作为弹窗的基类
class BaseStudentDialog(MessageBoxBase): # 定义一个学生信息弹窗的基类,继承自 MessageBoxBase
def __init__(self, title, parent=None):
super().__init__(parent) # 调用父类的初始化方法,设置父窗口
self.title = title # 保存弹窗标题,用于区分弹窗用途(如添加或修改学生信息)
self.setup_ui() # 调用界面设置方法,初始化弹窗界面
创建界面布局
编写一个setup_ui函数,用于定义窗口界面。我们采用viewLayout作为主布局,这是MessageBoxBase提供的默认布局,包含OK和Cancel按钮,无需重复创建。我们使用栅格布局(QGridLayout)绘制窗口表单。栅格布局适用于对齐内容。
创建栅格布局
创建一个名为grid_layout的栅格布局实例,并将其添加到主布局viewLayout中。
def setup_ui(self): # 定义设置用户界面的方法
grid_layout = QGridLayout() # 创建一个栅格布局对象,用于对控件进行行列排布
self.viewLayout.addLayout(grid_layout) # 将栅格布局添加到主视图布局中
定义表单字段
需要定义表单中的各项字段,包括姓名、学号、性别、班级以及语文、数学、英语成绩。每个字段的输入组件如下:
姓名:单行文本输入框,使用QLineEdit。
学号:单行文本输入框,同样使用QLineEdit。
性别:下拉菜单,使用QComboBox,添加“男”和“女”两个选项。
班级:下拉菜单,与性别类似。
三科成绩:单行文本输入框,分别定义语文、数学和英语成绩输入。
示例代码如下:
self.nameInput = LineEdit(self) # 创建一个单行文本输入框用于输入姓名
self.numberInput = LineEdit(self) # 创建一个单行文本输入框用于输入学号
self.genderCombo = ComboBox(self) # 创建一个下拉框组件用于选择性别
self.genderCombo.addItems(['男', '女']) # 为下拉框添加两个选项:男和女
self.classCombo = ComboBox(self) # 创建一个下拉框组件用于选择班级
self.chineseInput = LineEdit(self) # 创建一个单行文本输入框用于输入语文成绩
self.mathInput = LineEdit(self) # 创建一个单行文本输入框用于输入数学成绩
self.englishInput = LineEdit(self) # 创建一个单行文本输入框用于输入英语成绩
添加字段到网格布局
为简化布局,我们可以通过字典形式管理字段,并一一添加到栅格布局中。为了让弹窗的界面更加美观,我们使用了 QFluent 中的 StrongBodyLabel 样式来修饰文本标签。这一样式能够实现加粗效果,使界面更直观,代码如下:
# 定义字段标签与控件的映射
fields = [
("姓名:", self.nameInput), # 姓名字段与对应的输入框
("学号:", self.numberInput), # 学号字段与对应的输入框
("性别:", self.genderCombo), # 性别字段与对应的下拉框
("班级:", self.classCombo), # 班级字段与对应的下拉框
("语文:", self.chineseInput), # 语文字段与对应的输入框
("数学:", self.mathInput), # 数学字段与对应的输入框
("英语:", self.englishInput) # 英语字段与对应的输入框
]
# 遍历字段,添加到栅格布局中
for row, (label_text, widget) in enumerate(fields): # 使用 enumerate 获取字段的行号
label = StrongBodyLabel(label_text, self) # 创建加粗的标签
grid_layout.addWidget(label, row, 0) # 将标签添加到栅格布局的第一列
grid_layout.addWidget(widget, row, 1) # 将控件添加到栅格布局的第二列
布局的优化和对齐方式
为了保证界面在弹窗尺寸变化时保持整齐,我们设置了栅格的列拉伸属性,使其可以根据弹窗大小动态调整。我们还将所有字段设置为左对齐,确保布局一致:
# 设置列拉伸
grid_layout.setColumnStretch(1, 1) # 设置第二列的列拉伸系数为 1,确保控件能够自动适应窗口大小
# 设置标签对齐方式
grid_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 将控件对齐到左侧
确认和取消按钮的文本修改
弹窗中的按钮通常会有默认文本(如“OK”和“Cancel”),我们根据需求对其文本内容进行了自定义:
# 修改按钮文本
self.yesButton.setText('确定') # 将确认按钮文本设置为“确定”
self.cancelButton.setText('取消') # 将取消按钮文本设置为“取消”
在student/student_dialog.py 文件中界面布局整体代码如下:
# student/student_dialog.py文件中
from PyQt6.QtCore import Qt # 导入 PyQt6 模块中的 Qt 类,用于对齐方式等常量
from PyQt6.QtWidgets import QGridLayout # 导入 PyQt6 模块中的 QGridLayout,用于栅格布局
from qfluentwidgets import MessageBoxBase, ComboBox, LineEdit, StrongBodyLabel # 导入 qfluentwidgets 模块中的组件
class BaseStudentDialog(MessageBoxBase): # 定义一个学生信息弹窗的基类,继承自 MessageBoxBase
def __init__(self, title, parent=None): # 初始化方法,接收弹窗标题和父窗口作为参数
super().__init__(parent) # 调用父类的初始化方法,设置父窗口
self.title = title # 保存弹窗标题,用于区分弹窗用途(如添加或修改学生信息)
self.setup_ui() # 调用界面设置方法,初始化弹窗界面
def setup_ui(self): # 定义设置用户界面的方法
grid_layout = QGridLayout() # 创建一个栅格布局对象,用于对控件进行行列排布
self.viewLayout.addLayout(grid_layout) # 将栅格布局添加到主视图布局中
# 创建输入控件
self.nameInput = LineEdit(self) # 创建一个单行文本输入框用于输入姓名
self.numberInput = LineEdit(self) # 创建一个单行文本输入框用于输入学号
self.genderCombo = ComboBox(self) # 创建一个下拉框组件用于选择性别
self.genderCombo.addItems(['男', '女']) # 为下拉框添加两个选项:男和女
self.classCombo = ComboBox(self) # 创建一个下拉框组件用于选择班级
self.chineseInput = LineEdit(self) # 创建一个单行文本输入框用于输入语文成绩
self.mathInput = LineEdit(self) # 创建一个单行文本输入框用于输入数学成绩
self.englishInput = LineEdit(self) # 创建一个单行文本输入框用于输入英语成绩
# 定义字段标签与控件的映射
fields = [
("姓名:", self.nameInput), # 姓名字段与对应的输入框
("学号:", self.numberInput), # 学号字段与对应的输入框
("性别:", self.genderCombo), # 性别字段与对应的下拉框
("班级:", self.classCombo), # 班级字段与对应的下拉框
("语文:", self.chineseInput), # 语文字段与对应的输入框
("数学:", self.mathInput), # 数学字段与对应的输入框
("英语:", self.englishInput) # 英语字段与对应的输入框
]
# 遍历字段,添加到栅格布局中
for row, (label_text, widget) in enumerate(fields): # 使用 enumerate 获取字段的行号
label = StrongBodyLabel(label_text, self) # 创建加粗的标签
grid_layout.addWidget(label, row, 0) # 将标签添加到栅格布局的第一列
grid_layout.addWidget(widget, row, 1) # 将控件添加到栅格布局的第二列
# 设置列拉伸
grid_layout.setColumnStretch(1, 1) # 设置第二列的列拉伸系数为 1,确保控件能够自动适应窗口大小
# 设置标签对齐方式
grid_layout.setAlignment(Qt.AlignmentFlag.AlignLeft) # 将控件对齐到左侧
# 修改按钮文本
self.yesButton.setText('确定') # 将确认按钮文本设置为“确定”
self.cancelButton.setText('取消') # 将取消按钮文本设置为“取消”
领取专属 10元无门槛券
私享最新 技术干货