前言
上一节,我们已经实现类数据从文本文件中读取,以及加载显示在表格中,这一节我们要继续实现的内容是双击表格显示查看明细信息,选中某一条学生信息后点击修改按钮可以弹出修改学生明细信息的界面。点击添加按钮可以添加信息,点击删除按钮不弹出明细窗口,但是能通过对话框删除信息。
part4 加载明细窗体
一、以三种状态加载明细窗体
1. 需求分析
实现三种状态:
三种状态 | 输入框属性 | 标题 | 按钮情况 | 触发条件 |
---|---|---|---|---|
查看 | 只读 | 查看学生明细 | 只有关闭按钮 | 双击某一行数据 |
修改 | 除了学号,所有数据都可以修改 | 修改学生明细 | 有保存和关闭按钮 | 选中某一行数据,点击修改按钮 |
添加 | 所有的输入框为空 | 修改学生明细 | 有保存和关闭按钮 | 直接点击“添加”按钮 |
2. 实现方法
如何实现以三种不同状态来加载明细窗体呢?其实我们前面也做过类似案例,在加载明细窗体的时候携带一个参数flag
,通过参数的值判断是添加、修改、还是查看。
在studentdetail
这个类的初始化方法中添加一个int型的flag参数,并且在本地接收这个参数,判断这个参数的值。
(1)明细窗体做接受flag参数准备
我们定义一个方法load_gui_by_flag
目的为了根据不同flag的值加载不同的GUI状态,暂时先做修改标题的功能。
def load_gui_by_flag(self):
if self.flag == 1:
# 窗口为查看的状态
self.Label_Title["text"] = "查看学生明细"
elif self.flag == 2:
# 窗口为修改状态
self.Label_Title["text"] = "修改学生明细"
elif self.flag == 3:
# 窗口为添加的状态
self.Label_Title["text"] = "添加学生明细"
bind
方法,<Double-1>
代表双击事件。
接下来再定义一个打开窗体的方法view_student
来打开学生明细窗体。
注意:这里定义的view_student方法,需要多添加一个参数event
否则无法打开。
(3)给按钮添加功能
分别给添加按钮和删除按钮加上command
参数,其值分别为相应的方法。我们定义add_student
方法,给StudentDetail
传递参数3
,定义update_student
方法,给StudentDetail
传递参数2
。
这里我们先只写出方法雏形,接下来我们会继续完善。
二、数据表示
1. 需求分析
我们在记录和表示教师信息的时候有若干个字段,我们在传递数据的时候如果提供这么多参数会很麻烦,我们看能不能把这若干个参数封装成一个实体类。
2. 实现过程
我们在Service文件夹下新建一个person.py
文件,定义一个Person
实体类
class Person:
def __init__(self, name, gender, birthday, mobile, email):
self.name = name
self.gender = gender
self.birthday = birthday
self.mobile = mobile
self.email = email
Person
这个类来派生出Student
类和Teacher
类。
# 派生类 --- Student
class Student(Person):
def __init__(self, name, gender, birthday, mobile, email, sno, profession, study_time):
super().__init__(name, gender, birthday, mobile, email)
self.sno = sno
self.profession = profession
self.study_time = study_time
三、 查看学生明细信息
1. 需求分析
实现查看学生明细信息的窗口的绘制,我们需要满足的条件有: (1)修改Title为“查看学生明细” (2)隐藏保存按钮 (3)把双击的那行数据的填充到Entry (4)禁用所有的Entry (5)给按钮添加对应的功能
2. 实现过程
我们需要写的操作需要在studentdetail.py
中load_gui_by_flag
方法下完成。
(1)修改标题前面已经讲过了,实现方法为:
Button_save
在basedetail
使用palce
的方式布局的,所以这里我们使用place_forget()
方法对其进行隐藏。
(3)把双击选中的数据填充到Entry,我们要把数据传过来,这个数据怎么传过来呢?实现两个窗体之间的数据传递最基本的方法就是通过构造函数。所以我们的StudentDetail
类的构造函数除了要有flag
参数外,我们还应该添加一个参数current_student
,然后在该类中接收这个参数的值。
class StudentDetail(BaseDetail):
def __init__(self, flag: int, current_student):
super().__init__()
self.flag = flag
self.current_student = current_student
view_student
还需要添加功能以获取点击的内容。 首先我们需要在构造函数里提前添加一个空列表用来存储表格中被选中的学生。
以及定义flag
变量来标记窗口状态
最后完善view_student
函数,获取表格中双击的某一行的第一个数item
然后根据item
获取表格中存储的学生信息。
def view_student(self,event):
"""
双击某一行,加载明细信息
"""
# 获取点击的当前行
item = self.Tree_student.selection()[0] # 表示获取的当前行数据的第一个数
current_student = self.Tree_student.item(item, "values") # 根据id取出values
for item in self.student_all:
if current_student[0] == item[0]:
self.student_current = item
# 修改flag
self.flag = 1
# 以查看的形式加载
detail = StudentDetail(self.flag, self.student_current)
studentdetail
窗体现在开始准备接收数据。
以填充学生学号为例,我们需要先定义个存储学号的变量var_sno
,然后给输入学号的Entry
添加这个属性。我们才能在后面对这个Entry
进行赋值。
self.var_sno = StringVar()
self.Entry_sno = Entry(self.Pane_detail, textvariable=self.var_sno, font=("微软雅黑",13),width=12)
load_gui_by_flag
中,填充数据时直接使用set
方法即可。
这样我们就完成了,双击表格的某行,在明细窗口对学号的传递。
其余的组件也是同样的方法,以此类推。
self.var_sno.set(self.current_student[0])
self.var_name.set(self.current_student[1])
# 性别选项是Radio,需要判断一下。
if "男" in self.current_student[2]:
self.var_gender.set(1)
else:
self.var_gender.set(2)
self.var_birthday.set(self.current_student[3])
self.var_mobile.set(self.current_student[4])
self.var_email.set(self.current_student[5])
self.var_profession.set(self.current_student[6])
self.var_entry_time.set(self.current_student[7])
(4)禁用输入框
由于我们打开的是查看窗口,所以所有的输入框都应该是禁用状态。
输入框Entry
里有一个state
属性,我们给它赋一个值DISABLED
这个组建就被禁用了,显示成一个灰色
basedetail.py
,定义一个关闭当前GUI的函数close_gui
,然后给关闭按钮添加一个command
参数,再把close_gui
作为值赋给command
参数即可。
至此,我们的关闭功能也实现了,学生明细窗口基本完成了。
最后
本节,我们实现了查看明细窗体的功能,下一节,我们将定义一个Service类,以实现校验、修改、添加、删除和保存的功能。