本例的需求是:通過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() 即可。