本例的需求是:通过GUI录入界面将学生信息录入到系统中
(可以是数据库,或文件,本次使用txt文件读写)。如下图一:
=========================分界线========================
要求:1. 需要一个信息添加的GUI界面。
2. 功能: 检查各个参数是否合法
2.1 学号:95开头,6位数字。
2.2 姓名:汉字,不少于2个汉字,不大于10个汉字
2.3 性别: 【男| 女】
2.4 电话号码:满足电话号码规则
2.5 邮箱地址:满足邮箱地址规则
3. 添加信息的时候要判断 学号,姓名,电话号码和邮箱地址是否跟文件/数据库 中的信息重复。
类的架构设计:
实施:
1. 创建相应的py文件
2. studentgui.py
# -coding:utf-8-*-
from tkinter import *
from tkinter.messagebox import *
from tkinter.ttk import *
from studentservices import *
class StudentGUI(Tk):
def __init__(self):
super().__init__() # 初始化TK()类,并调用
self.title("添加学生信息")
self.geometry("400x500+400+200")
self.resizable(0, 0)
self["bg"] = "LightGray"
# 自动执行添加界面
self.setup_UI()
def setup_UI(self):
# 新建Style
self.style01 = Style()
self.style01.configure("TLabel", font=("微软雅黑", 14, "bold"), forground="navy", background="LightGray")
self.style01.configure("TButton", font=("微软雅黑", 14, "bold"), forground="navy", background="LightGray")
# ======学号========
self.Label_sno = Label(self, text="学号", width=10)
self.Label_sno.place(x=60, y=60)
self.var_sno = StringVar()
self.Entry_sno = Entry(self, textvariable=self.var_sno, font=("微软雅黑", 14, "bold"), width=10)
self.Entry_sno.place(x=120, y=60)
# ======姓名========
self.Label_name = Label(self, text="姓名", width=10)
self.Label_name.place(x=60, y=120)
self.var_name = StringVar()
self.Entry_name = Entry(self, textvariable=self.var_name, font=("微软雅黑", 14, "bold"), width=10)
self.Entry_name.place(x=120, y=120)
# ======性别========
self.Label_name = Label(self, text="性别", width=10)
self.Label_name.place(x=60, y=180)
self.var_gender = StringVar()
self.Entry_gender = Entry(self, textvariable=self.var_gender, font=("微软雅黑", 14, "bold"), width=10)
self.Entry_gender.place(x=120, y=180)
# ======电话号码========
self.Label_moblie = Label(self, text="电话号码:", width=10)
self.Label_moblie.place(x=60, y=240)
self.var_mobile = StringVar()
self.Entry_mobile = Entry(self, textvariable=self.var_mobile, font=("微软雅黑", 14, "bold"), width=15)
self.Entry_mobile.place(x=160, y=240)
# ======邮箱地址========
self.Label_email = Label(self, text="邮箱地址:", width=10)
self.Label_email.place(x=60, y=300)
self.var_email = StringVar()
self.Entry_email = Entry(self, textvariable=self.var_email, font=("微软雅黑", 14, "bold"), width=15)
self.Entry_email.place(x=160, y=300)
# ===== 提交=============
self.Button_commit = Button(self, text="提交", width=8, command=self.check_input)
self.Button_commit.place(x=240, y=360)
def check_input(self):
"""
:return:
"""
# 1, 将信息写入 StudentServices 类
current_student = StudentServices(self.var_sno.get(), self.var_name.get(), self.var_gender.get(),
self.var_mobile.get(), self.var_email.get())
# 2 将写入的信息进行判断
tag = current_student.check_student()
if tag == 2:
showinfo("系统消息:", "学号不符合要求")
elif tag == 3:
showinfo("系统消息:", "姓名不符合要求")
elif tag == 4:
showinfo("系统消息:", "性别不符合要求")
elif tag == 5:
showinfo("系统消息:", "电话号码不符合要求")
elif tag == 6:
showinfo("系统消息:", "邮箱地址不符合要求")
elif tag == 7:
showinfo("系统消息:", "学号已经存在!")
elif tag == 8:
showinfo("系统消息:", "姓名已经存在!")
elif tag == 9:
showinfo("系统消息:", "电话号码已经存在!")
elif tag == 10:
showinfo("系统消息:", "邮箱地址已经存在!")
elif tag == 1:
showinfo("系统消息:", "信息都符合要求,并且没有重名!")
# 3 写入到文件
student_info = Student(current_student.sno, current_student.name, current_student.gender, current_student.mobile, current_student.email)
try:
current_student.write_to_file(student_info)
showinfo("系统消息:", "写入文件成功")
except Exception as e:
showinfo("系统消息:", e)
if __name__ == '__main__':
gui = StudentGUI()
gui.mainloop()
if __name__ == '__main__':
gui = StudentGUI()
gui.mainloop()
check.py
import re
class Check:
def check_sno(self, sno):
pattern = re.compile("^95\d{4}$")
match_result = pattern.match(str(sno))
if match_result is None:
return False
else:
return True
def check_name(self, name):
# 校验是否小于10 并大于2
if len(name) <=10 and len(name) >=2:
for item in name:
if item < "\u4E00" and item > "\u9FA5":
return False
else:
return True
else:
return False
def check_gender(self, gender:str):
if gender.strip() in ["男", "女"]:
return True
else:
return False
def check_mobile(self, mobile):
pattern = re.compile(r"^1[3578]\d{9}$")
match_result = pattern.match(mobile)
if match_result is None:
return False
else:
return True
def check_email(self, email):
pattern = re.compile(r"\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}")
match_result = pattern.match(email)
if match_result is None:
return False
else:
return True
file.py
from student import *
class File:
def __init__(self, path):
self.path = path
print(self.path)
self.list_student_all = [] # 读取所有的学生信息后存储在该集合中
# 自动读取文件
self.read_from_file()
# self.write_to_file()
def read_from_file(self):
"""
读取文件中所有学生信息,然后存储到self.list_student_all 中
:return:
"""
try:
with open(self.path, mode="r", encoding="utf-8") as fd:
current_line = fd.readline()
# 判断是否读完
while current_line:
# 通过空格进行分割
student_list = current_line.split()
print(student_list)
temp_list = [] # 将一行信息写入
for item in student_list:
one_info_list = item.split(":")
# 添加 学生姓名
temp_list.append(one_info_list[1])
# 将一行信息添加
self.list_student_all.append(temp_list)
# 读取下一行
current_line = fd.readline()
print(self.list_student_all)
except Exception as e:
print(e)
def write_to_file(self, student_info: Student):
# 拼接学生信息 【2】 信息参数通过Student 来限定
# student_string = ""
student_string = "学号:" + student_info.sno + " " + "姓名:" + student_info.name + "" + "性别:" + student_info.gender \
+ "" + "手机号码:" + student_info.mobile + "" + "邮箱地址:" + student_info.email + "\n"
try:
with open(self.path, mode="a", encoding="utf-8") as fd:
fd.write(student_string)
# fd.write(student_info)
except Exception as e:
print(e)
上述的 student_string 的赋值 ":” 有误需要改为半角:
student.py
class Student:
def __init__(self, sno, name, gender, mobile, email):
self.sno = sno
self.name = name
self.gender = gender
self.mobile = mobile
self.email = email
studentservices.py
from check import *
from file import *
from student import *
class StudentServices(Check, File, Student):
# """
# 核心类
# 添加学生的核心功能
#
# """
def __init__(self, sno, name, gender, mobile, email):
self.path = "E:\\Temp\\Demo\\student.txt"
print(self.path)
Check.__init__(self)
File.__init__(self, self.path) # 初始化 file 类
Student.__init__(self, sno, name, gender, mobile, email)
def check_student(self):
# 要返回的值
return_flag = 0
if self.check_sno(self.sno) is False:
return_flag = 2 # 学号不符合要求,返回2
elif self.check_name(self.name) is False:
return_flag = 3 # 姓名不符合要求,返回3
elif self.check_gender(self.gender) is False:
return_flag = 4 # 性别不符合要求,返回4
elif self.check_mobile(self.mobile) is False:
return_flag = 5 # 电话号码不符合要求,返回5
elif self.check_email(self.email) is False:
return_flag = 6 # 邮箱地址不符合要求,返回6
elif self.sno_in_file():
return_flag = 7 # 学号已经存在,返回7
elif self.name_in_file():
return_flag = 8 # 姓名已经存在,返回8
elif self.mobile_in_file():
return_flag = 9 # 电话号码已经存在,返回9
elif self.email_in_file():
return_flag = 10 # 邮箱地址已经存在,返回10
else:
return_flag = 1
# 返回值
return return_flag
def sno_in_file(self):
"""
判断输入的学号是否存在于文件中!
:return:
"""
# 遍历文件读取的数据
for item in self.list_student_all:
if item[0] == str(self.sno):
return True
# 最后
return False
def name_in_file(self):
"""
判断输入的姓名是否存在于文件中!
:return:
"""
# 遍历文件读取的数据
for item in self.list_student_all:
if item[1] == str(self.name.strip()):
return True
# 最后
return False
def mobile_in_file(self):
"""
判断输入的电话号码是否存在于文件中!
:return:
"""
# 遍历文件读取的数据
for item in self.list_student_all:
# 第四列 是电话号码
if item[3] == str(self.mobile.strip()):
return True
# 最后
return False
def email_in_file(self):
"""
判断输入的邮箱地址是否存在于文件中!
:return:
"""
# 遍历文件读取的数据
for item in self.list_student_all:
if item[4] == str(self.email.strip()):
return True
# 最后
return False
遇到的几个问题:
1. 出现错误TypeError: expected string or bytes-like object
分析:类型错误,检查file 的txt文本的编码(一般是UTF-8)是否跟编译工具的一致?可以统一设置为UTF-8,文本另存为UTF-8 即可。
2. 出现 list index out of range
另一个可能是txt文件中的分隔符有问题 ,如下,手机号码后面的冒号未使用半角: 会无法分割
分析: 在txt文本 逐行读取信息的时候,按空格/tab键 分割的时候有误,我的是:
student_list = current_line.split(" ") 改为:
student_list = current_line.split() 即可。