Tkinter界面设计(运动会报名系统)
开发环境:
Ubuntu20.04
pycharm
MySQL数据库
需要下载的python库:
tkinter:图形界面设计库
pymysql:调用MySQL数据库的工具
sys:系统管理库,可更改迭代次数
pickle:包管理库,用于生成注册文件
功能实现:
两个主界面:运动员,裁判员;通过登陆时获取ID号进行区分,运动员需要注册并录入身份信息;
运动员界面功能:可报名项目预览,查看已报名项目,报名项目;
裁判员界面功能:查看项目报名情况,审核报名申请;
数据依赖于底层数据库,使用MySQL创建数据库sportmeeting,并建立以下几个表格:
xiangmu(用来存储项目的名称,时间地点,人数等);
yundongyuan(用来存储运动员身份信息);
xaipanyuan(用来存储裁判员身份信息,已提前录入);
baoming(用来存储报名时产生的申请信息);
xuliehao(一个值,用来给报名信息添加序号)
调用数据时使用cursor方法实现,具体代码如下:
sport = pymysql.connect(host='localhost',user='root',passwd='密码',db='数据库名',port=3306,charset='utf8')
con = sport.cursor()
con.execute("mysql命令")(注意命令需要大写)
data = con.fetchall()
引入pymysql库后,使用上述语句可以在python中调用数据库进行增删改查;
设计思路(附代码):
注:代码部分可直接按顺序粘贴运行,底层数据库需自行搭建
开始时先创建数据库链接,数据库可根据需求自己创建:
#链接数据库:
def Sportingmeeting():
global data1,data2,con
sport = pymysql.connect(host='localhost',user='root',passwd='pass123',db='sportmeeting',port=3306,charset='utf8')
con = sport.cursor()
con.execute("SELECT ID from caipanyuan")
data11 = con.fetchall()
con.execute("SELECT name,time,address,zongshu,yicanjia from xiangmu")
data2 = con.fetchall()
data1 = []
for i in range(len(data11)):
data1.append(data11[i][0])
return data1,data2,con
#连接数据库,将裁判员的ID号读入到data1;将项目的名称,时间,地点,数量读入到data2
Sportingmeeting()
然后开始登录和注册界面设计:
包括登录情况判断函数,注册函数,登录和注册界面,用户区分运动员和裁判员,登录后获取ID号进行区分,分别打开不同的主界面:
#开始界面
def Start():
w0 = Tk()
w0.title("运动会报名系统")
w0.geometry('480x400+500+150') # 这里的乘是小x
photo = tk.PhotoImage(file="/home/andy/Pictures/beiing1.png")
theLabel = tk.Label(w0, justify=tk.LEFT, image=photo, compound=tk.CENTER) # 背景图片
theLabel.pack()
l1 = Label(w0, text="欢迎进入运动会系统!", width="480", height="5")
l2 = Label(w0, text="已有账号:",bg='lightblue', width="50", height="2")
l2.place(relx=0.3, rely=0.2, anchor=CENTER)
l3 = Label(w0, text="还未注册账号?",bg='lightblue', width="50", height="2")
l3.place(relx=0.3, rely=0.4, anchor=CENTER)
b1 = Button(w0, text="登录", width="10", height="1", command=lambda: [w0.destroy(), Deng()])
b1.place(relx=0.6, rely=0.2, anchor=CENTER)
b2 = Button(w0, text="立即注册", width="10", height="1", command=lambda: [w0.destroy(), Zhuce()])
b2.place(relx=0.6, rely=0.4, anchor=CENTER)
l2 = Label(w0,bg='lightblue', width="50", height="2")
l2.place(relx=0.8, rely=0.8, anchor=CENTER)
b3 = Button(w0, text="退出", width="10", height="1", command=w0.destroy)
b3.place(relx=0.5, rely=0.8, anchor=CENTER)
l1.pack()
w0.mainloop()
# 登录界面:
def Deng():
# 登录情况判断函数:
def Denglu():
global Name
Name = t1.get()
Pass = t2.get()
ming = str(Name.replace('\n', ''))
con.execute("SELECT ID from caipanyuan")
data11 = con.fetchall()
con.execute("SELECT name,time,address,zongshu,yicanjia from xiangmu")
data2 = con.fetchall()
data1 = []
for i in range(len(data11)):
data1.append(str(data11[i][0]))
try:
with open('注册表.pickle', 'rb') as users:
info = pickle.load(users)
except FileNotFoundError:
with open('注册表.pickle', 'wb') as users:
info = {'a': '123456'}
pickle.dump(info, users)
if Name in info:
if Pass == info[Name]:
if ming in data1:
tk.messagebox.showinfo(title="登录成功", message="欢迎你")
w1.destroy()
Caipanyuan()
#如果ID号在data1中,则打开裁判员审核界面
else:
tk.messagebox.showinfo(title="登录成功", message="欢迎你")
w1.destroy()
Yundongyuan() # 打开运动员报名界面
else:
tk.messagebox.showerror(message='密码错误!')
elif Name == "" or Pass == "":
tk.messagebox.showerror(message='用户名或密码不能为空!')
else:
Y = tk.messagebox.showerror('你好像还没有注册哟,是否现在注册?')
if Y:
Zhuce() # 打开注册界面
#这里是登录界面
w1 = Tk()
w1.title("运动会报名系统登陆界面")
w1.geometry('400x300+500+150') # 这里的乘是小x
photo = tk.PhotoImage(file="/home/andy/Pictures/beiing1.png")
theLabel = tk.Label(w1, justify=tk.LEFT, image=photo, compound=tk.CENTER) # 前景色
theLabel.pack()
l1 = Label(w1, text="欢迎进入登录界面,请输入账号密码,注意区分大小写:", width="480", height="4")
ID = Label(w1, text="学号:")
ID.place(relx=0.2, rely=0.2, anchor=CENTER)
Password = Label(w1, text="密码:")
Password.place(relx=0.2, rely=0.4, anchor=CENTER)
t1 = tk.Entry(w1)
t1.place(relx=0.5, rely=0.2, anchor=CENTER, width=200, height=25)
t2 = tk.Entry(w1, show="*")
t2.place(relx=0.5, rely=0.4, anchor=CENTER, width=200, height=25)
b3 = Button(w1, text="登录", width="10", height="1", command=lambda: [Denglu()])
b3.place(relx=0.3, rely=0.6, anchor=CENTER)
b4 = Button(w1, text="返回", width="10", height="1", command=lambda: [w1.destroy(), Start()])
b4.place(relx=0.7, rely=0.6, anchor=CENTER)
l1.pack()
w1.mainloop()
# 注册界面:
def Zhuce():
def Zhucehanshu():
yy = y1.get()
tt = t7.get()
rr = r8.get()
ID =y1.get()
name=y2.get()
age=y3.get()
sex=y4.get()
dianhua=y5.get()
nothing=1
#获取各个输入框的值
try:
with open("注册表.pickle", 'rb') as users:
einfo = pickle.load(users)
except FileNotFoundError:
einfo = {}
if yy in einfo:
tk.messagebox.showerror(title="错误!", message="用户名已存在。")
elif yy == '' or tt == '': \
tk.messagebox.showerror(title="错误!", message="用户名或密码不能为空。")
elif tt != rr:
tk.messagebox.showerror(title="错误!", message="密码前后不一致。")
else:
einfo[yy] = tt
with open("注册表.pickle", 'wb') as users:
pickle.dump(einfo, users)
tk.messagebox.showinfo(title="欢迎!", message="注册成功。")
b5.destroy()
ID1 = str(ID.replace('\n', ''))
if ID1 in data1:
nothing = 0
else:
con.execute("INSERT INTO yundongyuan(ID,name,sex,age,dianhua) VALUES('%s','%s','%s','%s','%s')" % (
ID, name, sex, age, dianhua))
sport.commit()#将各个输入框的值添加到数据库的运动员表中
# 注册界面
w3 = Tk()
w3.title("用户注册")
w3.geometry('500x480+300+100')
photo = tk.PhotoImage(file="/home/andy/Pictures/beiing1.png")
theLabel = tk.Label(w3, justify=tk.LEFT, image=photo, compound=tk.CENTER) # 前景色
theLabel.pack()
l4 = Label(w3, text="请输入学号或工号:")
l4.place(relx=0.2, rely=0.2, anchor=CENTER)
l4 = Label(w3, text="请输入姓名:")
l4.place(relx=0.2, rely=0.3, anchor=CENTER)
l4 = Label(w3, text="您的年龄:")
l4.place(relx=0.2, rely=0.4, anchor=CENTER)
l4 = Label(w3, text="您的性别:")
l4.place(relx=0.2, rely=0.5, anchor=CENTER)
l4 = Label(w3, text="您的联系电话::")
l4.place(relx=0.2, rely=0.6, anchor=CENTER)
l5 = Label(w3, text="请输入登录密码:")
l5.place(relx=0.2, rely=0.7, anchor=CENTER)
l5 = Label(w3, text="请再次输入登录密码:")
l5.place(relx=0.2, rely=0.8, anchor=CENTER)
y1 = tk.Entry(w3)
y1.place(relx=0.5, rely=0.2, anchor=CENTER, width=200, height=25)
y2 = tk.Entry(w3)
y2.place(relx=0.5, rely=0.3, anchor=CENTER, width=200, height=25)
y3 = tk.Entry(w3)
y3.place(relx=0.5, rely=0.4, anchor=CENTER, width=200, height=25)
y4 = tk.Entry(w3)
y4.place(relx=0.5, rely=0.5, anchor=CENTER, width=200, height=25)
y5 = tk.Entry(w3)
y5.place(relx=0.5, rely=0.6, anchor=CENTER, width=200, height=25)
t7 = tk.Entry(w3, show="*")
t7.place(relx=0.5, rely=0.7, anchor=CENTER, width=200, height=25)
r8 = tk.Entry(w3, show="*")
r8.place(relx=0.5, rely=0.8, anchor=CENTER, width=200, height=25)
b5 = Button(w3, text="确认注册", command=lambda: [Zhucehanshu()])
b5.place(relx=0.8, rely=0.8, anchor=CENTER, width=75, height=25)
b6 = Button(w3, text="返回", command=lambda: [w3.destroy(), Start()])
b6.place(relx=0.8, rely=0.9, anchor=CENTER, width=75, height=25)
w3.mainloop()
界面运行效果:
运动员报名界面的设计:
主要包括项目预览,报名申请提交,报名信息查询功能
#运动员报名界面:
def Yundongyuan():
Name1=int(Name)
con.execute("SELECT ID,name,sex,age,dianhua FROM yundongyuan WHERE ID = %s"%Name1)
gerenxx = con.fetchone()#背景图片
# print(gerenxx)
def Yulan():
con.execute("SELECT name,time,address,zongshu,yicanjia FROM xiangmu")
xiangmusj = con.fetchall()
global l04#声明全局变量,使得其他按钮可以关闭该界面
l04 = ttk.Treeview(w00,show='headings') # 表格
l04["columns"] = ("项目名称", "时间", "地点","剩余名额")
l04.column("项目名称",width=120) # 表示列
l04.column("时间",width=120)
l04.column("地点",width=80)
l04.column("剩余名额",width=70)
l04.heading("项目名称", text="项目名称") # 显示表头
l04.heading("时间", text="时间")
l04.heading("地点", text="地点")
l04.heading("剩余名额", text="剩余名额")
shengyu=[]
for i in range(len(xiangmusj)):
shengyu.append(int(xiangmusj[i][3])-int(xiangmusj[i][4]))
l04.insert("", 4, text="1", values=(xiangmusj[i][0],xiangmusj[i][1],xiangmusj[i][2],shengyu[i]))
l04.place(relx=0.4, rely=0.22)#将剩余名额计算后添加到列表中
#报名按钮回调函数:
def Baoming():
b1.config(state='disabled')
b2.config(state='disabled')
l05 = LabelFrame(w00, text='请勾选你想要报名的项目:', padx=5, pady=5)
l05.place(relx=0.2, rely=0.1)
v1 = IntVar()
v2 = IntVar()
v3 = IntVar()
v4 = IntVar()
v5 = IntVar()
v6 = IntVar()
v7 = IntVar()
v8 = IntVar()
v9 = IntVar()
v10 = IntVar()
v11= IntVar()
v12 = IntVar()
v13 = IntVar()
v14 = IntVar()
v15 = IntVar()
v16 = IntVar()
v17 = IntVar()
v18 = IntVar()
v19 = IntVar()
v20 = IntVar()
v = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,v11, v12,v13,v14 ,v15, v16,
v17, v18, v19, v20]
con.execute("SELECT name FROM xiangmu")
xiangmuname = con.fetchall()
#确定报名按钮回调函数
def callCheckbutton():
a=[]
for j in range(20):
a.append(v[j].get())
# con.execute("SELECT ID FROM xiangmu")
# xiangID = con.fetchall()
# print(xiangID)
con.execute("SELECT name FROM xiangmu")
xiangmuname = con.fetchall()
# print(xiangmuname)
# print(a)
sheng = '待审核'
yunID=Name1
xiangID=[1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1098]
#读出运动员ID,项目ID,生成序号,将数据添加到baoming数据表中,并将数据库中的序列号加1
for k in range(len(a)):
if a[k]==1:
con.execute("SELECT id FROM xuliehao")
hao = con.fetchone()
haoold = hao[0]
haonew = haoold + 1
# haonew1=str(haonew)
print(haonew)
con.execute("UPDATE xuliehao SET id = %s", haonew)
sport.commit()
xiangID1=xiangID[k]
con.execute("SELECT yicanjia FROM xiangmu WHERE ID='%s'",xiangID1)
coount2 = con.fetchone()
print(coount2[0])
coount2=coount2[0]+1
con.execute("UPDATE xiangmu SET yicanjia = '%s' WHERE ID='%s' ",(coount2,xiangID[k]))
sport.commit()
con.execute("INSERT INTO baoming(xiangmuID,yundongyuanID,shenghe,xuhao) VALUES('%s','%s','%s','%s')"%(xiangID[k],yunID,sheng,haonew))
sport.commit()
else:
continue
for i in range(len(v)):
Checkbutton(l05, variable=v[i], bg='white', anchor='w', width=20, text=xiangmuname[i]).grid()
b05 = Button(w00,text='确定报名', bg='white',width=10, height=1,command=lambda: [
tk.messagebox.showinfo(title="报名成功", message="请等待管理员审核!"),
callCheckbutton()])
b06 = Button(w00, text='返回', bg='white', width=10, height=1, command=lambda: [
b1.config(state='normal'),
b2.config(state='normal'),
l05.destroy(),b05.destroy(),b06.destroy()])
b05.place(relx=0.55, rely=0.84,anchor=CENTER)
b06.place(relx=0.55, rely=0.89,anchor=CENTER)
#我的项目回调函数
#查询我已报名的项目ID,再从xiangmu数据表中查询项目信息,打印到lable中
def Myproject():
global l05
con.execute("SELECT xiangmuID FROM baoming WHERE yundongyuanID = %s" % Name1)
myjects = con.fetchall()
myjects3 = []
for i in range(len(myjects)):
x = str(myjects[i][0])
x1 = x.replace(',', '')
x2 = x1.replace('(', '')
x3 = x2.replace(')', '')
# print(x3)
con.execute("SELECT name,time,address FROM xiangmu WHERE ID = %s" % x3)
myjects2 = con.fetchone()
if myjects2 not in myjects3:
myjects3.append(myjects2)
con.execute("SELECT shenghe FROM baoming WHERE yundongyuanID = %s" % Name1)
myjects5 = con.fetchall()
print(myjects5[0][0])
l05 = ttk.Treeview(w00, show='headings') # 表格
l05["columns"] = ("项目名称", "时间", "地点", "审核情况")
l05.column("项目名称", width=120) # 表示列,不显示
l05.column("时间", width=120)
l05.column("地点", width=80)
l05.column("审核情况", width=70)
l05.heading("项目名称", text="项目名称") # 显示表头
l05.heading("时间", text="时间")
l05.heading("地点", text="地点")
l05.heading("审核情况", text="审核情况")
l05.insert("", 4, text="1", values=("男子3000米", "12月12日上午9:00", "一号田径场", "待审核"))
for i in range(len(myjects3)):
l05.insert("", 4, text="1", values=(myjects3[i][0],myjects3[i][1],myjects3[i][2],myjects5[i][0]))
l05.place(relx=0.4, rely=0.22)
#主界面
w00 = Tk()
w00.title("运动员报名界面")
w00.geometry('700x600+300+100')
photo = tk.PhotoImage(file="/home/andy/Pictures/bj22.png")
theLabel = tk.Label(w00, justify=tk.LEFT, image=photo, compound=tk.CENTER) # 前景色
theLabel.pack()
ft1 = tkFont.Font(family='黑体',weight=tkFont.BOLD,size=30)
l1 = Label(w00, text='运动会报名系统',font=ft1, bg='lightblue', fg='black', width=70)
l1.place(relx=0.5, rely=0.05,anchor=CENTER)
l2 = Label(w00, text='个人信息',font='ft1', bg='lightblue', fg='black', width=23, height=1)
l2.place(relx=0.21, rely=0.2,anchor=CENTER)
items1 = ('学号:','姓名:','年龄:','性别:','联系电话:')
strvar_items1 = StringVar(value=items1)
l002 = Listbox(w00, listvariable=strvar_items1, width=28, height=5)
l002.place(relx=0.05, rely=0.22)
iitems2 = (gerenxx[0], gerenxx[1],gerenxx[2],gerenxx[3],gerenxx[4])
siitems2 = StringVar(value=iitems2)
l02 = Listbox(w00, listvariable=siitems2, width=20, height=5)
l02.place(relx=0.14, rely=0.22)
l3 = Label(w00, text='项目预览',font='ft1', bg='lightblue', fg='black', width=39, height=1)
l3.place(relx=0.68, rely=0.2,anchor=CENTER)
b1=Button(w00,text='项目预览',width=10, height=1,command=lambda: [l3.config(text='项目预览'),Yulan()])
# b1.place(relx=0.06, rely=0.5)
b2=Button(w00,text='我的项目',width=10, height=1,command=lambda: [l3.config(text='我报名的项目'),b1.place(relx=0.06, rely=0.5),Myproject()])
b2.place(relx=0.06, rely=0.6)
b3=Button(w00,text='我要报名',width=10, height=1,command=lambda: [b1.place(relx=0.06, rely=0.5),Baoming()])
b3.place(relx=0.06, rely=0.7)
b3 = Button(w00, text='注销', width=10, height=1, command=lambda: [w00.destroy(),Start()])
b3.place(relx=0.06, rely=0.9)
Yulan()
w00.mainloop()
运行效果:
裁判员审核界面的设计:
主要包括报名情况预览,报名申请审核和问题处理功能
#裁判员审核界面
def Caipanyuan():
sport = pymysql.connect(host='localhost', user='root', passwd='pass123', db='sportmeeting', port=3306,
charset='utf8')
con = sport.cursor()
w01 = Tk()
w01.title("裁判员审核界面")
w01.geometry('700x600+300+100')
photo = tk.PhotoImage(file="/home/andy/Pictures/bj12.png")
theLabel = tk.Label(w01, justify=tk.LEFT, image=photo, compound=tk.CENTER) # 前景色
theLabel.pack()
#审核情况预览回调函数
def Qingkuang():
global l11
con.execute("SELECT name,time,address,zongshu,yicanjia yicanjia FROM xiangmu")
xiangmusj = con.fetchall()
l11 = ttk.Treeview(w01, height=20, show='headings') # 表格
l11["columns"] = ("项目名称", "时间", "地点", "总数", "已参加")
l11.column("项目名称", width=110) # 表示列,不显示
l11.column("时间", width=120)
l11.column("地点", width=80)
l11.column("总数", width=35)
l11.column("已参加", width=40)
l11.heading("项目名称", text="项目名称") # 显示表头
l11.heading("时间", text="时间")
l11.heading("地点", text="地点")
l11.heading("总数", text="总数")
l11.heading("已参加", text="已参加")
for i in range(len(xiangmusj)):
l11.insert("", 5, text="1",
values=(xiangmusj[i][0], xiangmusj[i][1], xiangmusj[i][2], xiangmusj[i][3], xiangmusj[i][4]))
l11.place(relx=0.4, rely=0.22)
#审核函数,根据选择的值改变审核情况(待审核或已通过),并修改数据库中该项目的值
def Shenghe():
b1.config(state='disabled')
global l12
def Tongyi():
tong=v.get()
# print(tong)
# print(int(x3[0]))
if tong==1:
con.execute("UPDATE baoming SET shenghe = '已通过' WHERE xuhao='%s' ",int(x3[0]))
sport.commit()
l12.destroy()
b11.destroy()
b12.destroy()
b13.destroy()
b14.destroy()
Shenghe()#重新调用审核函数,显示下一条数据
else:
l12.destroy()
b11.destroy()
b12.destroy()
b13.destroy()
b14.destroy()
Shenghe()
con.execute("SELECT xuhao,yundongyuanID,xiangmuID FROM baoming WHERE shenghe='待审核' ")
x3 = con.fetchone()
# print(x3)
con.execute("SELECT name,age,sex,dianhua FROM yundongyuan WHERE ID='%s'",int(x3[1]))
x4 = con.fetchone()
yun=['.................','姓名:'+str(x4[0]),'年龄:'+str(x4[1]),'性别:'+str(x4[2]),'电话:'+str(x4[3])]
# print(x4)
con.execute("SELECT name,time,address,yicanjia,zongshu FROM xiangmu WHERE ID='%s'", int(x3[2]))
x5 = con.fetchone()
xiang= ['................','项目:' +str(x5[0]), '时间:' +str(x5[1]), '地点:' +str(x5[2]), '已参加人数:' +str(x5[3]),'总人数:'+str(x5[4])]
# print(x5)
l12=Label(w01,bg='white',width=50, height=25)
l12.place(relx=0.6, rely=0.5, anchor=CENTER)
l112 = Listbox(l12, bg='white', width=40, height=8)
for item in xiang:
l112.insert(END,item)
l112.place(relx=0.5, rely=0.6, anchor=CENTER)
l13 = Label(l12, text='报名项目:', bg='white', width=50, height=2)
l13.place(relx=0.19, rely=0.4, anchor=CENTER)
l113 = Listbox(l12, bg='white', width=40, height=5)
for item in yun:
l113.insert(END,item)
l113.place(relx=0.5, rely=0.25, anchor=CENTER)
l14 = Label(l12, text='运动员信息:', bg='white', width=50, height=2)
l14.place(relx=0.2, rely=0.1, anchor=CENTER)
v=tk.IntVar()
b11 = Radiobutton(w01, text='同意',bg='white',variable=v,value=1, width=8, height=1)
b11.place(relx=0.4, rely=0.7)
b12 = Radiobutton(w01, text='不同意',bg='white', variable=v,value=2,width=8, height=1)
b12.place(relx=0.6, rely=0.7)
b13 = Button(w01, text='确定', width=6, height=1, command=lambda: [Tongyi()])
b13.place(relx=0.75, rely=0.75)
b14 = Button(w01, text='返回', width=6, height=1, command=lambda: [
b1.config(state='normal'),l12.destroy(),b11.destroy(),b12.destroy(),b13.destroy(),b14.destroy()
])
b14.place(relx=0.75, rely=0.8)
ft1 = tkFont.Font(family='宋体',weight=tkFont.BOLD,size=30)
l1 = Label(w01, text='运动会报名系统',font=ft1, bg='seashell', fg='black', width=70)
l1.place(relx=0.5, rely=0.05,anchor=CENTER)
b1=Button(w01,text='报名情况预览',width=10, height=2,command=lambda: [l12.destroy(),Qingkuang()])
b2=Button(w01,text='报名申请审核',width=10, height=2,command=lambda: [b1.place(relx=0.05, rely=0.4),Shenghe(),l11.destroy()])
b2.place(relx=0.05, rely=0.5)
b3 = Button(w01, text='注销', width=10, height=1, command=lambda: [w01.destroy(), Start()])
b3.place(relx=0.05, rely=0.85)
Qingkuang()
w01.mainloop()
运行效果:
最后添加入口:
#入口:
Start()#开始界面
几个关键部分:
1.tkinter库在安装时要注意python版本问题,如果安装不上切换其他版本试一试,在使用时操作比较简单,容易上手,但是没有可视化设计软件,所以在调参数时非常辛苦,这里建议使用pyqt5进行设计,该软件可提供可视化设计软件QTdesigner,并支持直接转换成python代码运行,比tkinter节省很多时间;
2.在各函数间调用时要尤其注意全局变量和局部变量的区别,以保证函数调用正常;
3.各界面相互转换时用到button的回调函数,注意函数生成的位置,不可以在按钮生成后再生成回调函数,否则会报错,无法找到命令,另外切换子界面时要注意各界面的消失和出现,理清各界面的出现顺序,在调试期间经常出现界面重叠等问题,十分麻烦;
4.调用数据库中的数据时经常出现格式上的问题,比如多一些标点符号等,这里提出两个解决方案,一是在建立数据库时多测试几遍,看看存储的数据是什么格式,并使用合适的数据类型进行录入;而是在调用数据时对数据进行格式化,去掉多余符号,改变字符类型或使用正则表达式等。
总结:
tkinter学习起来比较简单,但经常需要GUI界面开发的话推荐使用pyqt,会更节省时间,插件也比较丰富,做出来效果更好;使用数据库存储底层数据要比从其他文件中读取更加方便,也比较安全和实用,将数据库的使用与操作界面设计紧密结合起来,将是未来开发项目的重点。