最后,附上完整代码,其中附有详细注释:
# -*- coding: utf-8 -*- # @Author:︶ㄣ释然 # @Time: 2022/7/6 22:08 import tkinter as tk # 定义一个全局变量接收学生信息并进行更新 LIST = [] # 定义一个方法用于使用w模式写入文件:传入已经存好变更好信息的列表,然后遍历写入txt文档 def writeTxt_wMode(studentList): # w:只写入模式,文件不存在则建立,将文件里边的内容先删除再写入 with open("test.txt", "w", encoding="utf-8") as f: for i in range(0, len(studentList)): DICT = studentList[i] if i == len(studentList) - 1: f.write("{0}\t{1}\t{2}".format(DICT["name"], DICT["sex"], DICT["phone"])) else: f.write("{0}\t{1}\t{2}\n".format(DICT["name"], DICT["sex"], DICT["phone"])) # 定义一个方法用于读取文件: def readTxt() -> list: emptyList1 = [] emptyList2 = [] # 打开同目录下的txt文件 f = open("./test.txt", 'r', encoding='UTF-8') # 把txt文件中的每一行学生信息,存储为新列表emptyList1的元素, for i in f: a = str(i) b = a.replace('\n', '') emptyList1.append(b.split("\t")) # 依次将emptyList的三种学生信息字典,存入列表 while len(emptyList2) < len(emptyList1): for j in range(0, len(emptyList1)): name = emptyList1[j][0] sex = emptyList1[j][1] phone = emptyList1[j][2] Dict = {"name": name, "sex": sex, "phone": phone} # 把该字典作为emptyList2的一个元素,依次存入。 emptyList2.append(Dict) f.close() # 最后结束方法,返回存储信息完成的列表 return emptyList2 # 定义一个方法,检查输入的电话号码是否符合规范,返回布尔值 def checkPhoneNumber_Boolean(phone): if phone.isdigit(): return True else: result.set("电话号码输入不是纯数字") return False # 定义一个方法,去除字符串左右两端的空格,并返回处理之后的字符串 def trim(strings): # 获取从偏移为0的字符一直到偏移为1的字符串,不包括偏移为1的字符串 # (该功能用于去除字符串左边的空格) while strings[:1] == ' ': strings = strings[1:] # 获取从偏移为-1的字符一直到偏移为最后一位的字符串,不包括偏移为最后一位的字符串 # (该功能用于去除字符串右边的空格) while strings[-1:] == ' ': strings = strings[:-1] # 左右两端空格去除完成,返回strings return strings # 定义方法查找同名 def checkTheSameName(enterName): flagList = [] # 存的是名字的索引 List = [] returnList = [] date = 1 # 开始遍历查找 for i in range(0, len(LIST)): if LIST[i]["name"] == enterName: # 把找到的名字对应的索引,添加进列表 flagList.append(int(i)) if len(flagList) == 1: # 说明信息中只存在一个这样的名字 return date # 返回1表示不重名 if len(flagList) > 1: for i in flagList: List.append(LIST[i]) # 此时,List的长度等于flagList returnList.append(List) returnList.append(flagList) return returnList # 第一个元素是列表,第二个元素是存储重复名字的索引的 列表 # 定义方法显示所有重复的学生信息 def show_ofTheSameName(list_ofTheSameName): # 定义一个字符串用于存储想要输出显示的内容 str_out = "" str_out += "出现同名,同名学生信息显示如下:\n" # 打印头部标题 并进行格式化 str_out += ("{:^9}".format("学生序号") + "{:^9}".format("学生姓名") + "{:^9}".format("学生性别") + "{:^11}".format("电话号码") + "\n") for i in range(0, len(list_ofTheSameName)): # 格式化字符串 str_out += ("{:<11}".format(i + 1, chr(12288)) + "{:<11}".format(list_ofTheSameName[i].get("name"), chr(12288)) + "{:^9}".format(list_ofTheSameName[i].get("sex"), chr(12288)) + "{:>15}".format(list_ofTheSameName[i].get("phone"), chr(12288)) + "\n") str_out += "\n请在上方输入详细学生信息,进行精准删除" result.set(str_out) # 定义方法清除gui界面的三个学生信息 def delete_Gui_StudentMessage(): textName.set("") textSex.set("") textPhone.set("") # 1、添加学生信息 def addStudentsMessage(): # 在gui界面输入的学生姓名,使用get()方法,获取entry中输入的内容 # 并且用name接收 name = textName.get() # 判断是否为空,并在gui界面进行提示 if not name: result.set("学生姓名不能为空") return # 调用自定义的方法,去除字符串两端的空格再进行比较,如果去除空格之后为空,则说明键入的字符串只有空格 if trim(name) == "": result.set("学生姓名不能为空") return # 判断性别输入是否正确 # 在gui界面输入的学生性别,使用get()方法,获取entry中输入的内容 # 并且用sex接收 sex = textSex.get() if sex == "F" or sex == "M": pass else: # 如果输入的性别不符合规范,则在gui界面进行提示 result.set("性别输入格式有误") return # 判断电话输入是否正确 # 在gui界面输入的学生电话号码,使用get()方法,获取entry中输入的内容 # 并且用phone接收 phone = textPhone.get() # 调用自定义的检查方法,返回布尔类型,如果符合要求,则返回True resultBoolean = checkPhoneNumber_Boolean(phone) if resultBoolean: pass else: return Dict = {"name": name, "sex": sex, "phone": phone} LIST.append(Dict) result.set("学生已添加") # 调用自定义方法清除gui界面的学生信息 delete_Gui_StudentMessage() writeTxt_wMode(LIST) return # 2、删除学生信息 def deleteMessage() -> list: # 定义信号位 flag = True enterName = textName.get() for i in range(0, len(LIST)): if LIST[i]["name"] == enterName: flag = False break if flag: result.set("学生不存在") # 学生不存在则没有必要查找是否同名 return LIST # 开始遍历查找 accept = checkTheSameName(enterName) # 接收查找同名方法的返回值 if accept == 1: for i in range(0, len(LIST)): if LIST[i]["name"] == enterName: del LIST[i] result.set("删除成功") writeTxt_wMode(LIST) delete_Gui_StudentMessage() # 删除成功直接返回,结束该方法 return else: # 此时出现同名,accept[0]和accept[1]都是列表对象 # accept[0]存储的是同名学生信息 show_ofTheSameName(accept[0]) for i in range(0, len(LIST)): if LIST[i]["name"] == textName.get(): if LIST[i]["sex"] == textSex.get(): if LIST[i]["phone"] == textPhone.get(): del LIST[i] result.set("删除成功") writeTxt_wMode(LIST) delete_Gui_StudentMessage() return # 3、修改学生信息 def change(): if LIST is None: result.set("没有信息,无法修改") return None if len(LIST) == 0: result.set("没有信息,无法修改") return None if len(LIST) != 0: inputName = textName.get() for i in range(0, len(LIST)): if LIST[i]["name"] == inputName: LIST[i]["sex"] = textSex.get() LIST[i]["phone"] = textSex.get() writeTxt_wMode(LIST) result.set("修改成功") delete_Gui_StudentMessage() return # 4、显示所有学生信息 def show(): # 定义一个字符串用于存储想要输出显示的内容 str_out = "" if LIST is None: result.set("无学生信息") return if len(LIST) == 0: result.set("无学生信息") return if len(LIST) != 0: str_out += "学生信息如下:\n" # 打印头部标题 并进行格式化 str_out += ("{:^9}".format("学生序号") + "{:^9}".format("学生姓名") + "{:^9}".format("学生性别") + "{:^11}".format("电话号码") + "\n") for i in range(0, len(LIST)): # 格式化字符串 str_out += ("{:<11}".format(i + 1, chr(12288)) + "{:<11}".format(LIST[i].get("name"), chr(12288)) + "{:^9}".format(LIST[i].get("sex"), chr(12288)) + "{:>15}".format(LIST[i].get("phone"), chr(12288)) + "\n") # 在gui界面更新显示最新的字符串str result.set(str_out) # 把文件里边的学生信息添加到LIST1里边,如果发现文件里边的学生信息为空,则继续执行后面的程序 try: for i in readTxt(): LIST.append(i) except: pass # 关于gui的代码, 用方法封装比较困难, # 此处利用if __name__ == '__main__' , 方便代码折叠, ”阅读”全局思路 if __name__ == '__main__': # 以下代码全部为gui界面的初始化 # 第1步,实例化对象,建立窗口window window = tk.Tk() # 第2步,给窗口的可视化起名字 window.title('学生信息管理系统 V3.0') # 学生信息管理系统6 - 1 # 第3步,设定窗口的大小(长 * 宽) window.geometry('500x650') # tk.StringVar()用于接收用户输入 result = tk.StringVar() result.set(" ") # ①关于姓名的 label 和 entry textName = tk.StringVar() textName.set("") labelLine1 = tk.Label(window, text="姓 名:", font=('Arial', 15), width=10).place(x=75, y=50, anchor='nw') entryLine1 = tk.Entry(window, show=None, font=('宋体', 15), textvariable=textName, width=20) entryLine1.place(x=190, y=50, anchor='nw') # 显示成明文形式 # ②关于性别的 label 和 entry textSex = tk.StringVar() textSex.set("") labelLine2 = tk.Label(window, text="性 别:", font=('Arial', 15), width=10) labelLine2.place(x=75, y=100, anchor='nw') entryLine2 = tk.Entry(window, show=None, font=('Arial', 15), textvariable=textSex, width=18) entryLine2.place(x=190, y=100, anchor='nw') # ③关于电话的 label 和 entry textPhone = tk.StringVar() textPhone.set("") labelLine3 = tk.Label(window, text="电 话:", font=('Arial', 15), width=10).place(x=75, y=150, anchor='nw') entryLine3 = tk.Entry(window, show=None, font=('Arial', 15), textvariable=textPhone, width=18) entryLine3.place(x=190, y=150, anchor='nw') # 关于"添加"组件,此处绑定函数addStudentsMessage()用于添加学生信息 button1_add = tk.Button(window, text='添 加', bg='silver', font=('Arial', 12), command=addStudentsMessage, width=8) button1_add.place(x=40, y=220, anchor='nw') # 关于"删除"组件,此处绑定函数deleteMessage()用于删除学生信息 button2_delete = tk.Button(window, text='删 除', bg='silver', font=('Arial', 12), command=deleteMessage, width=8) button2_delete.place(x=150, y=220, anchor='nw') # 关于"修改"组件,此处绑定函数change()用于修改学生信息 button3_change = tk.Button(window, text='修 改', bg='silver', font=('Arial', 12), command=change, width=8) button3_change.place(x=260, y=220, anchor='nw') # 关于"显示"组件,此处绑定函数show()用于显示学生信息 button4_show = tk.Button(window, text='显 示', bg='silver', font=('Arial', 12), command=show, width=8) button4_show.place(x=370, y=220, anchor='nw') # 下边两行代码是在gui界面显示我的作者信息 labelLine_Name = tk.Label(window, text="@Author:", font=('宋体', 13), width=10).place(x=130, y=260, anchor='nw') labelLine_myID = tk.Label(window, text="︶ㄣ释然", font=('宋体', 13), width=10).place(x=250, y=260, anchor='nw') show_result = tk.Label(window, bg="white", fg="black", font=("宋体", 12), bd='0', anchor='nw', textvariable=result) show_result.place(x="25", y="300", width="450", height="300") window.mainloop()