发布时间:2024-01-15 15:30
本题为数据库的一项课程作业,结合Python和Sql实现了学生选课管理系统,感觉反正都写了,就给大家做一下参考吧,可能会对Tkinter的应用有一些帮助,注释有些乱,凑活看吧。
刚开始用Tkinter的时候踩了很多坑,虽然都说Tkinter简单易上手,但我感觉做不出来太高端的东西...如果时间比较充裕倒是可以学一下QT,时间短想突击一下还是可以用一下Tkinter的
P.S:突然感觉php也比这个强一点哈哈
代码分为menu.py和main.py两个部分,基本功能实现都在menu里,main中实现了调用。
这次课设是我第一次学习用Python编程,之前一直都是用的C++的,所以很多地方对于Python的应用并不是很熟悉,都是简简单单照葫芦画瓢能用就行了,并没有深究,细看的话还有很多地方可以优化的。不过笔者还是比较懒的,最后能用就没管那么多了hhh
话不多说,下面附上代码。
友情提示:代码中的pymysql.connect中的用户名、密码、数据库名我都没改,如果想应用在自己电脑上的话需要根据自己MySql的账号密码对其进行修改,数据库没有可以仿照着操作中的名称建立数据库
menu.py:
import tkinter
from tkinter import *
from tkinter import ttk
from tkinter.messagebox import showinfo, showerror, askyesno
from PIL import Image, ImageTk
import pymysql
# 选课的我想设置一个课程冲突提醒
# GUI界面布局:https://blog.csdn.net/superfanstoprogram/article/details/83713196
# 亟待解决的问题:showerror报错时总会跟着弹出主窗口 #解决了
class menu(object):
def __init__(self, master, handle, user_name=None): # master参数指的是父容器
self.window = master
self.user_handle = handle
self.user_name = user_name
self.window.iconphoto(False, ImageTk.PhotoImage(file=\'icon2.png\'))
self.window.resizable(False, False) # 不可更改大小
self.sid = StringVar() # 学生身份证
self.name = StringVar() # 姓名
self.sex = StringVar() # 性别
self.dept_name = StringVar() # 单位(院系名)
self.age = StringVar() # 年龄
# stu_reward添加
self.type = StringVar()
self.info = StringVar()
# dept_info添加
self.major_name = StringVar()
# course
self.cid = StringVar()
self.course_name = StringVar()
self.teacher = StringVar()
self.time = StringVar()
self.classroom = StringVar()
self.credit = StringVar()
# exam添加
self.score = StringVar()
# self.window.geometry(\'500x400\')
self.handle = False # 设置句柄,为真时代表已经有一个窗口了,禁止再打开新窗口
self.handle_2 = False # 代表修改院系信息的那个窗口
self.createWindow()
def get_image(self, filename, width, height):
im = Image.open(filename).resize((width, height))
return ImageTk.PhotoImage(im)
def center_show(self):
ScreenWid, ScreenHei = self.window.maxsize()
CurWid = 500
CurHeight = 400
cen_x = (ScreenWid - CurWid) / 2
cen_y = (ScreenHei - CurHeight) / 2
size_xy = \'%dx%d+%d+%d\' % (CurWid, CurHeight, cen_x, cen_y)
return size_xy
def createWindow(self):
# command不能加参数,加参数自动执行了!!括号也不行!!代表空值也是参数!!!
# 若想传入参数且不自动执行需要格式为 command = lambda:function(1)
# 链接:https://blog.csdn.net/guge907/article/details/23291763
self.window.geometry(self.center_show())
# # 背景图片
canvas_root = tkinter.Canvas(self.window, width=500, height=400)
# im_root = Image.open(\'technology.jpg\').resize((500, 400))
# im = ImageTk.PhotoImage(im_root)
im = self.get_image(\'city.png\', 500, 400)
canvas_root.create_image(250, 200, image=im) # 参数取窗口大小的一半!!!!!!!!!
canvas_root.pack()
# imLabel = Label(self.window, image=img).place(relx=0,rely=0)
Button(self.window, text=\'学生信息\', command=self.stu_info).place(relx=0.05, rely=0.05, relwidth=0.2)
Button(self.window, text=\'奖惩情况\', command=self.stu_reward).place(relx=0.3, rely=0.05, relwidth=0.2)
Button(self.window, text=\'院系情况\', command=self.dept_info).place(relx=0.05, rely=0.15, relwidth=0.2)
Button(self.window, text=\'课程管理\', command=self.course).place(relx=0.3, rely=0.15, relwidth=0.2)
Button(self.window, text=\'学生选课管理\', command=self.course_selection).place(relx=0.05, rely=0.25, relwidth=0.2)
Button(self.window, text=\'考试管理\', command=self.exam).place(relx=0.3, rely=0.25, relwidth=0.2)
Button(self.window, text=\'补考重修\', command=self.exam_makeup).place(relx=0.05, rely=0.35, relwidth=0.2)
# con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
self.window.mainloop() # !!!!!!!!!!!!!!
def stu_info(self): # 学生信息
if not self.handle: # 只有handle为False时(代表无该窗口存在)才能执行建立窗口的语句
self.handle = True
top = Toplevel(self.window)
self.window.withdraw()
# 居中显示
ScreenWid, ScreenHei = top.maxsize()
CurWid = 800
CurHeight = 600
cen_x = (ScreenWid-CurWid)/2
cen_y = (ScreenHei-CurHeight)/2
size_xy = \'%dx%d+%d+%d\' % (CurWid, CurHeight, cen_x, cen_y)
top.geometry(size_xy)
# **************居中显示语句结束
Label(top, text=\'学号:\').grid(row=0, column=0, pady=5)
Label(top, text=\'姓名:\').grid(row=1, column=0, pady=5)
Label(top, text=\'性别:\').grid(row=2, column=0, pady=5)
Label(top, text=\'年龄:\').grid(row=3, column=0, pady=5)
Label(top, text=\'单位:\').grid(row=4, column=0, pady=5)
Entry(top, textvariable=self.sid).grid(row=0, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.name).grid(row=1, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.sex).grid(row=2, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.age).grid(row=3, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.dept_name).grid(row=4, column=1, pady=5, ipadx=60)
Button(top, text=\'显示所有学生信息\', command=lambda: self.show_stu_info(tree)).grid(row=0, column=2, padx=200, ipadx=35)
Button(top, text=\'添加学生信息\', command=lambda: self.add_stu_info(tree)).grid(row=1, column=2, padx=200, ipadx=50)
Button(top, text=\'查询学生信息\', command=lambda: self.search_stu_info(tree)).grid(row=2, column=2, padx=200, ipadx=50)
Button(top, text=\'删除学生信息\', command=lambda: self.delete_stu_info(tree)).grid(row=3, column=2, padx=200, ipadx=50)
Button(top, text=\'修改学生信息\', command=lambda: self.modify_stu_info(tree)).grid(row=4, column=2, padx=200, ipadx=50)
# treeview的相关操作参考网站 https://www.jb51.net/article/209215.htm
tree = ttk.Treeview(top, show=\'headings\', column=(\'sid\', \'name\', \'sex\', \'age\', \'dept_name\'))
tree.place(rely=0.35, width=CurWid, relheight=0.6)
tree.column(\'sid\', width=150, anchor=\"center\")
tree.column(\'name\', width=200, anchor=\"center\")
tree.column(\'sex\', width=100, anchor=\"center\")
tree.column(\'age\', width=150, anchor=\"center\")
tree.column(\'dept_name\', width=150, anchor=\"center\")
tree.heading(\'sid\', text=\'学号\')
tree.heading(\'name\', text=\'姓名\')
tree.heading(\'sex\', text=\'性别\')
tree.heading(\'age\', text=\'年龄\')
tree.heading(\'dept_name\', text=\'单位\')
# top.geometry(\'400x500\')
top.title(\"学生信息\")
top.protocol(\"WM_DELETE_WINDOW\", lambda: self.quit(top)) # 点击窗口关闭按钮时,自动调用quit函数
def quit(self, master):
self.handle = False
master.destroy()
self.window.deiconify()
# 这下面的语句是为了关闭时清空输入框
self.sid = StringVar() # 学生身份证
self.name = StringVar() # 姓名
self.sex = StringVar() # 性别
self.dept_name = StringVar() # 单位(院系名)
self.age = StringVar() # 年龄
# stu_reward添加
self.type = StringVar()
self.info = StringVar()
# dept_info添加
self.major_name = StringVar()
# course
self.cid = StringVar()
self.course_name = StringVar()
self.teacher = StringVar()
self.time = StringVar()
self.classroom = StringVar()
self.credit = StringVar()
# exam
self.score = StringVar()
# END**************
# 展示所有学生信息
def show_stu_info(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
x = tree.get_children()
# for item in x:
# print(tree.item(item, \"values\"))
# print(x)
for item in x:
tree.delete(item)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
cur.execute(\"select * from stu_info order by sid\")
lst = cur.fetchall()
# treeview的插入方法
for item in lst:
tree.insert(\"\", END, values=item) # END表示插入表格末尾
cur.close()
con.close()
# 关于点击一下标题更换排序方式(升序/降序),可参考博客 https://blog.csdn.net/sinat_27382047/article/details/80161637
# 添加学生信息
def add_stu_info(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
ans = askyesno(title=\'提示\', message=\'是否进行当前操作\')
if ans is True:
if self.sid.get() == \"\" or self.name.get() == \"\" or self.sex.get() == \"\" or self.age.get() == \"\" \\
or self.dept_name.get() == \"\":
showerror(title=\'提示\', message=\'请输入完整信息!\')
else:
# x = tree.get_children()
# for item in x:
# tree.delete(item)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sid = self.sid.get()
name = self.name.get()
sex = self.sex.get()
age = self.age.get()
dept_name = self.dept_name.get()
# 检验SID是否已经存在
sqlSearch = \"select * from stu_info where sid = %s\"
result = cur.execute(sqlSearch, sid)
if result > 0:
showerror(title=\"提示\", message=\"学号已存在!\")
else:
sql = \"insert into stu_info values(%s,%s,%s,%s,%s)\"
try:
cur.execute(sql, (sid, name, sex, age, dept_name))
con.commit()
# showinfo(title=\"提示\", message=\"添加成功!\")
tree.insert(\"\", END, values=(sid, name, sex, age, dept_name))
except:
showerror(title=\'提示\', message=\'添加失败,请检查是否输入信息过长或者出现格式错误\')
# cur.execute(\"select * from stu_info order by sid\")
# lst = cur.fetchall()
cur.close()
con.close()
# 删除学生信息
def delete_stu_info(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
ans = askyesno(title=\'提示\', message=\'是否进行当前操作\')
if ans is True:
if self.sid.get() == \'\':
showerror(title=\'提示\', message=\'请输入学号\')
else:
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
line = cur.execute(\"delete from stu_info where sid = %s\", self.sid.get())
if line == 0:
showerror(title=\"提示\", message=\"删除失败,请检查学号是否输入正确\")
else:
showinfo(title=\"提示\", message=\"删除成功!\")
con.commit()
cur.close()
con.close()
self.show_stu_info(tree)
# 查询学生信息
# 如果输入了学号则优先只按照学号查找,若学号一栏为空,则其余栏的内容可以进行混合查找
def search_stu_info(self, tree):
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sign = 0 # sign=0表示还没有碰到不为空的entry
# 先清除原始数据
x = tree.get_children()
for item in x:
tree.delete(item)
if self.user_handle:
# print(self.user_name)
cur.execute(\"select * from stu_info where sid = %s\", self.user_name)
lst = cur.fetchone()
# print(lst)
tree.insert(\"\", END, values=lst)
cur.close()
con.close()
return
# 这个学号查询不用管,因为肯定至多一个元组,不可能有多个结果
if self.sid.get() != \"\":
sqlname_1 = \"select * from stu_info where sid = %s\"
result = cur.execute(sqlname_1, self.sid.get())
if result < 1:
showerror(title=\'提示\', message=\'未找到相关学生\')
else:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
cur.close()
con.close()
return # 尝试一下能不能至此直接跳过函数后边的语句 # 可以
if self.name.get()!=\"\":
sqlname_2 = \"select * from stu_info where name like \'%%%%%s%%%%\'\"
sqlname_2 = sqlname_2 % (self.name.get())
result = cur.execute(sqlname_2)
lst = cur.fetchall()
if result < 1:
showerror(title=\'提示\', message=\'未找到相关学生\')
else:
for item in lst:
tree.insert(\"\", END, values=item)
if self.sex.get() != \"\":
temp = tree.get_children() #不知道tree为空的时候返回值是什么,我写if temp is None 也不对
temp_length = 0
# 怎么直接判断temp是否为空啊
for item in temp:
temp_length += 1
if temp_length == 0:
cur.execute(\"select * from stu_info order by sid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
temp_2 = tree.get_children()
for item in temp_2:
# print((tree.item(item, \"values\"))[2])
if (tree.item(item, \"values\"))[2] != self.sex.get():
tree.delete(item)
temp_length -= 1
if temp_length == 0:
# print(tree.get_children())
showerror(title=\'提示\', message=\'未找到相关学生\')
# 年龄查找我决定用一个跟性别查找不太一样的方法,设置一个标志变量sign
if self.age.get() != \"\":
# 重复的初始化工作******************
temp = tree.get_children()
temp_length = 0
for item in temp:
temp_length += 1
if temp_length == 0:
cur.execute(\"select * from stu_info order by sid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
# 初始化结束*************************************
sign = False # sign为False代表暂时没找到符合条件的学生
temp_2 = tree.get_children()
for item in temp_2:
if (tree.item(item, \"values\"))[3] != self.age.get():
tree.delete(item)
else:
sign = True
if sign is False:
showerror(title=\'提示\', message=\'未找到相关学生\')
# 单位查询
if self.dept_name.get() != \"\":
# 重复的初始化工作******************
temp = tree.get_children()
temp_length = 0
for item in temp:
temp_length += 1
if temp_length == 0:
cur.execute(\"select * from stu_info order by sid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
# 初始化结束*************************************
sign = False # sign为False代表暂时没找到符合条件的学生
temp_2 = tree.get_children()
for item in temp_2:
if (tree.item(item, \"values\"))[4] != self.dept_name.get():
tree.delete(item)
else:
sign = True
if sign is False:
showerror(title=\'提示\', message=\'未找到相关学生\')
if self.sid.get() == \"\" and self.name.get() == \"\" and self.sex.get() == \"\" and self.age.get() == \"\" \\
and self.dept_name.get() == \"\":
showerror(title=\'提示\', message=\'请至少输入一条查询信息\')
con.close()
cur.close()
def modify_stu_info(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
ans = askyesno(title=\'提示\', message=\'是否进行当前操作\')
if ans is True:
if self.sid.get() == \"\" and self.name.get() == \"\" and self.sex.get() == \"\" and self.age.get() == \"\" \\
and self.dept_name.get() == \"\":
showerror(title=\'提示\', message=\'请输入完整信息!\')
else:
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sql = \'update stu_info set name=%s, sex=%s, age=%s, dept_name=%s where sid=%s\'
try:
cur.execute(sql,(self.name.get(), self.sex.get(), self.age.get(), self.dept_name.get(), self.sid.get()))
# showinfo(title=\'提示\', message=\'修改成功!\')
con.commit()
self.show_stu_info(tree)
except:
con.rollback()
showerror(title=\"提示\", message=\"修改失败!请检查信息格式!\")
con.close()
cur.close()
def stu_reward(self): # 奖惩情况 reward or punish
# 主码为sid 并且有name列,另有type列以及info列 分别代表奖励或者惩罚(type)、具体简洁信息(info)
if not self.handle: # 只有handle为False时(代表无该窗口存在)才能执行建立窗口的语句
self.handle = True
top = Toplevel(self.window)
self.window.withdraw()
# 居中显示
ScreenWid, ScreenHei = top.maxsize()
CurWid = 800
CurHeight = 600
cen_x = (ScreenWid - CurWid) / 2
cen_y = (ScreenHei - CurHeight) / 2
size_xy = \'%dx%d+%d+%d\' % (CurWid, CurHeight, cen_x, cen_y)
top.geometry(size_xy)
# ****************
Label(top, text=\'学号:\').grid(row=0, column=0, pady=5)
Label(top, text=\'姓名:\').grid(row=1, column=0, pady=5)
Label(top, text=\'类型:\').grid(row=2, column=0, pady=5)
Label(top, text=\'备注信息:\').grid(row=3, column=0, pady=5)
Entry(top, textvariable=self.sid).grid(row=0, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.name).grid(row=1, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.type).grid(row=2, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.info).grid(row=3, column=1, pady=5, ipadx=60)
tree = ttk.Treeview(top, show=\'headings\', column=(\'sid\', \'name\', \'type\', \'info\'))
Button(top, text=\'显示所有奖惩信息\', command=lambda: self.show_stu_reward(tree)).grid(row=0, column=2, padx=200, ipadx=35)
Button(top, text=\'添加奖惩信息\', command=lambda: self.add_stu_reward(tree)).grid(row=1, column=2, padx=200, ipadx=50)
Button(top, text=\'查询奖惩信息\', command=lambda: self.search_stu_reward(tree)).grid(row=2, column=2, padx=200, ipadx=50)
Button(top, text=\'删除奖惩信息\', command=lambda: self.delete_stu_reward(tree)).grid(row=3, column=2, padx=200, ipadx=50)
Button(top, text=\'修改奖惩信息\', command=lambda: self.modify_stu_reward(tree)).grid(row=4, column=2, padx=200, ipadx=50)
tree.place(rely=0.35, width=CurWid, relheight=0.6)
tree.column(\'sid\', width=100, anchor=\"center\")
tree.column(\'name\', width=100, anchor=\"center\")
tree.column(\'type\', width=100, anchor=\"center\")
tree.column(\'info\', width=350, anchor=\"center\")
tree.heading(\'sid\', text=\'学号\')
tree.heading(\'name\', text=\'姓名\')
tree.heading(\'type\', text=\'类型\')
tree.heading(\'info\', text=\'备注信息\')
top.title(\'奖惩情况\')
top.protocol(\"WM_DELETE_WINDOW\", lambda: self.quit(top))
def show_stu_reward(self, tree):
x = tree.get_children()
for item in x:
tree.delete(item)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
if self.user_handle: # 如果是学生
cur.execute(\"select * from stu_reward where sid = %s\", self.user_name)
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item) # END表示插入表格末尾
cur.close()
con.close()
return
cur.execute(\"select * from stu_reward order by sid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item) # END表示插入表格末尾
cur.close()
con.close()
def add_stu_reward(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
ans = askyesno(title=\'提示\', message=\'是否进行当前操作\')
if ans is True:
if self.sid.get() == \"\" or self.name.get() == \"\" or self.type.get() == \"\" or self.info.get() == \"\" :
showerror(title=\'提示\', message=\'请输入完整信息!\')
else:
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sid = self.sid.get()
name = self.name.get()
type = self.type.get()
info = self.info.get()
# 检验SID是否已经存在
sqlSearch = \"select * from stu_info where sid = %s and name=%s\"
result = cur.execute(sqlSearch, (sid, name))
if result == 0:
showerror(title=\"提示\", message=\"对应学生不存在!请检索学生信息表!\")
else:
sql = \"insert into stu_reward values(%s,%s,%s,%s)\"
try:
cur.execute(sql, (sid, name, type, info, ))
con.commit()
tree.insert(\"\", END, values=(sid, name, type, info))
except:
showerror(title=\'提示\', message=\'添加失败,请检查是否输入信息过长或者出现格式错误\')
cur.close()
con.close()
def delete_stu_reward(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
ans = askyesno(title=\'提示\', message=\'是否进行当前操作\')
if ans is True:
if self.sid.get() == \'\':
showerror(title=\'提示\', message=\'请输入学号\')
else:
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
# 这里不加换行符行吗?***************
line = cur.execute(\"delete from stu_reward where sid = %s and type = %s and info = %s\",
(self.sid.get(), self.type.get(), self.info.get()))
if line == 0:
showerror(title=\"提示\", message=\"删除失败,请检查是否输入正确(学号,类型,备注信息)\")
else:
showinfo(title=\"提示\", message=\"删除成功!\")
con.commit()
cur.close()
con.close()
self.show_stu_reward(tree)
# 查询奖惩信息
# 还是一样的,当有学号时直接结束函数,返回学号等于当前值的全部数据 当然可以再优化一下,但我现在不想写了T_T
def search_stu_reward(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sign = 0 # sign=0表示还没有碰到不为空的entry
# 先清除原始数据
x = tree.get_children()
for item in x:
tree.delete(item)
if self.sid.get()!=\"\":
sqlname_1 = \"select * from stu_reward where sid = %s\"
result = cur.execute(sqlname_1, self.sid.get())
if result < 1:
showerror(title=\'提示\', message=\'未找到相关信息\')
else:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
cur.close()
con.close()
return
# name查找
if self.name.get()!=\"\":
sqlname_2 = \"select * from stu_reward where name like \'%%%%%s%%%%\'\"
sqlname_2 = sqlname_2 % (self.name.get())
result = cur.execute(sqlname_2)
lst = cur.fetchall()
if result < 1:
showerror(title=\'提示\', message=\'未找到相关学生\')
else:
for item in lst:
tree.insert(\"\", END, values=item)
# type查找
if self.type.get() != \"\":
temp = tree.get_children() #不知道tree为空的时候返回值是什么,我写if temp is None 也不对
temp_length = 0
# 怎么直接判断temp是否为空啊
for item in temp:
temp_length += 1
# 如果type查询之前得到的tree为空,则利用当前type值对table进行搜索,得到所有的type等于当前值的元组
if temp_length == 0:
sql = \"select * from stu_reward where type = %s order by sid\"
cur.execute(sql, self.type.get())
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
temp_length += 1
# 不管上面的if语句有没有执行,程序运行到此tree中一定已经有了部分数据(当然也有可能还是空的)
# 还要执行for循环的意义在于:有可能上述if语句没有执行,那么tree中得到的数据并不一定都是满足type等于当前值的
# 所以需要进行一次for循环将tree中type值不符合条件的数据删掉
temp_2 = tree.get_children()
for item in temp_2:
# print((tree.item(item, \"values\"))[2])
if (tree.item(item, \"values\"))[2] != self.type.get():
tree.delete(item)
temp_length -= 1
if temp_length == 0:
# print(tree.get_children())
showerror(title=\'提示\', message=\'未找到相关学生\')
# info查找
if self.info.get() != \"\":
# 重复的初始化工作******************
temp = tree.get_children()
temp_length = 0
for item in temp:
temp_length += 1
if temp_length == 0:
sql = \"select * from stu_reward where info = %s order by sid\"
cur.execute(sql, self.info.get())
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
temp_length += 1
# 初始化结束*************************************
temp_2 = tree.get_children()
for item in temp_2:
if (tree.item(item, \"values\"))[3] != self.info.get():
tree.delete(item)
temp_length -= 1
if temp_length == 0:
showerror(title=\'提示\', message=\'未找到相关学生\')
if self.sid.get() == \"\" and self.name.get() == \"\" and self.type.get() == \"\" and self.info.get() == \"\":
showerror(title=\'提示\', message=\'请至少输入一条查询信息\')
con.close()
cur.close()
# 有一个比较严重的问题,姓名如果改了那么另一个表里学号对应的姓名也需要改,否则会有冲突,要处理好两个表共同拥有的属性
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
def modify_stu_reward(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
ans = askyesno(title=\'提示\', message=\'是否进行当前操作\')
if ans is True:
if self.sid.get() == \"\" and self.name.get() == \"\" and self.type.get() == \"\" and self.info.get() == \"\":
showerror(title=\'提示\', message=\'请输入完整信息!\')
else:
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sql = \'update stu_reward set name=%s, type=%s, info=%s where sid=%s\'
try:
cur.execute(sql,
(self.name.get(), self.type.get(), self.info.get(), self.sid.get()))
# showinfo(title=\'提示\', message=\'修改成功!\')
sql = \'update stu_info set name = %s where sid = %s\'
cur.execute(sql, (self.name.get(), self.sid.get()))
self.show_stu_reward(tree)
con.commit()
except:
con.rollback()
showerror(title=\"提示\", message=\"修改失败!请检查信息格式!或检查学生信息中有无此人!\")
self.show_stu_reward(tree)
con.close()
cur.close()
def dept_info(self): # 院系情况
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
if not self.handle: # 只有handle为False时(代表无该窗口存在)才能执行建立窗口的语句
self.handle = True
top = Toplevel(self.window)
self.window.withdraw()
handle_dept = False # False代表没有开窗口
# 居中显示
ScreenWid, ScreenHei = top.maxsize()
CurWid = 800
CurHeight = 600
cen_x = (ScreenWid - CurWid) / 2
cen_y = (ScreenHei - CurHeight) / 2
size_xy = \'%dx%d+%d+%d\' % (CurWid, CurHeight, cen_x, cen_y)
top.geometry(size_xy)
# ****************
Label(top, text=\'学院名称:\').grid(row=0, column=0, pady=5)
Label(top, text=\'专业名称:\').grid(row=1, column=0, pady=5)
Entry(top, textvariable=self.dept_name).grid(row=0, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.major_name).grid(row=1, column=1, pady=5, ipadx=60)
tree = ttk.Treeview(top, show=\'headings\', column=(\'dept_name\', \'major_name\'))
Button(top, text=\'显示所有院系信息\', command=lambda: self.show_dept_info(tree)).grid(row=0, column=2, padx=200, ipadx=35)
Button(top, text=\'查询院系信息\', command=lambda: self.search_dept_info(tree)).grid(row=1, column=2, padx=200, ipadx=50)
Button(top, text=\'修改院系信息\', command=lambda: self.modify_dept_info(tree, top)).grid(row=2, column=2, padx=200, ipadx=50)
tree.place(rely=0.25, width=CurWid, relheight=0.6)
tree.column(\'dept_name\', width=300, anchor=\"center\")
tree.column(\'major_name\', width=300, anchor=\"center\")
tree.heading(\'dept_name\', text=\'学院名称\')
tree.heading(\'major_name\', text=\'专业名称\')
top.title(\'院系情况\')
top.protocol(\"WM_DELETE_WINDOW\", lambda: self.quit(top))
# 退出修改院系信息
def quit_2(self, master):
master.destroy()
self.handle_2 = False
def show_dept_info(self, tree):
x = tree.get_children()
for item in x:
tree.delete(item)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
cur.execute(\"select * from dept_info order by dept_name\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item) # END表示插入表格末尾
cur.close()
con.close()
# 不能增加信息,只能设置或修改信息
def search_dept_info(self, tree):
# 先清除原始数据
x = tree.get_children()
for item in x:
tree.delete(item)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
# dept_name查找
if self.dept_name.get() != \"\":
sqlname_2 = \"select * from dept_info where dept_name like \'%%%%%s%%%%\'\"
sqlname_2 = sqlname_2 % (self.dept_name.get())
result = cur.execute(sqlname_2)
lst = cur.fetchall()
if result < 1:
showerror(title=\'提示\', message=\'未找到相关学院\')
else:
for item in lst:
tree.insert(\"\", END, values=item)
# major_name查找
if self.major_name.get() != \"\":
temp = tree.get_children() # 不知道tree为空的时候返回值是什么,我写if temp is None 也不对
temp_length = 0
# 怎么直接判断temp是否为空啊
for item in temp:
temp_length += 1
# 如果major_name查询之前得到的tree为空,则利用当前major_name值对table进行搜索,得到所有的major_name等于当前值的元组
if temp_length == 0:
sql = \"select * from dept_info where major_name like \'%%%%%s%%%%\' order by dept_name\"
cur.execute(sql, self.major_name.get())
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
temp_length += 1
# 不管上面的if语句有没有执行,程序运行到此tree中一定已经有了部分数据(当然也有可能还是空的)
# 还要执行for循环的意义在于:有可能上述if语句没有执行,那么tree中得到的数据并不一定都是满足major_name等于当前值的
# 所以需要进行一次for循环将tree中major_name值不符合条件的数据删掉
temp_2 = tree.get_children()
for item in temp_2:
# print((tree.item(item, \"values\"))[2])
if self.major_name.get() not in (tree.item(item, \"values\"))[1]:
tree.delete(item)
temp_length -= 1
if temp_length == 0:
# print(tree.get_children())
showerror(title=\'提示\', message=\'未找到相关信息\')
def modify_dept_info(self, tree, master):
if not self.handle_2:
self.handle_2 = True
top = Toplevel(master)
top.resizable(False, False)
# 居中显示
ScreenWid, ScreenHei = top.maxsize()
CurWid = 400
CurHeight = 300
cen_x = (ScreenWid - CurWid) / 2
cen_y = (ScreenHei - CurHeight) / 2
size_xy = \'%dx%d+%d+%d\' % (CurWid, CurHeight, cen_x, cen_y)
top.geometry(size_xy)
# ****************
Label(top, text=\'原学院名称:\').place(relx=0.1, rely=0.2)
pre_name=Entry(top)
pre_name.place(relx=0.32, rely=0.2)
Label(top, text=\'更改后学院名称:\').place(relx=0.04, rely=0.3)
new_name=Entry(top)
new_name.place(relx=0.32,rely=0.3)
butt_1=Button(top,text=\'修改学院名称\',command=lambda:self.modify_dept_name(pre_name.get(), new_name.get()))
butt_1.place(relx=0.05,rely=0.8)
Label(top, text=\'原专业名称:\').place(relx=0.1, rely=0.45)
pre_name_2 = Entry(top)
pre_name_2.place(relx=0.32, rely=0.45)
Label(top, text=\'更改后专业名称:\').place(relx=0.04, rely=0.55)
new_name_2 = Entry(top)
new_name_2.place(relx=0.32, rely=0.55)
butt_2 = Button(top, text=\'修改专业名称\', command=lambda: self.modify_major_name(pre_name_2.get(), new_name_2.get()))
butt_2.place(relx=0.7, rely=0.8)
top.protocol(\"WM_DELETE_WINDOW\",lambda:self.quit_2(top))
def modify_dept_name(self, pre_name, new_name):
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sign = 0
sql = \'update dept_info set dept_name = %s where dept_name = %s\'
sql_2 = \'update stu_info set dept_name = %s where dept_name = %s\'
try:
cur.execute(sql, (new_name, pre_name))
cur.execute(sql_2, (new_name, pre_name))
con.commit()
except:
con.rollback()
showerror(title=\'提示\', message=\'修改失败!\')
sign = 1
if sign == 0:
showinfo(title=\'提示\', message=\'修改成功!\')
con.close()
cur.close()
def modify_major_name(self, pre_name, new_name):
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sql = \'update dept_info set major_name = %s where major_name = %s\'
result = cur.execute(sql, (new_name, pre_name))
if result < 1:
showerror(title=\'提示\', message=\'修改失败!\')
else:
showinfo(title=\'提示\', message=\'修改成功!\')
con.commit()
con.close()
cur.close()
def course(self): # 课程管理
if not self.handle: # 只有handle为False时(代表无该窗口存在)才能执行建立窗口的语句
self.handle = True
top = Toplevel(self.window)
self.window.withdraw()
# 居中显示
ScreenWid, ScreenHei = top.maxsize()
CurWid = 800
CurHeight = 600
cen_x = (ScreenWid - CurWid) / 2
cen_y = (ScreenHei - CurHeight) / 2
size_xy = \'%dx%d+%d+%d\' % (CurWid, CurHeight, cen_x, cen_y)
top.geometry(size_xy)
# ****************
top.title(\'课程管理\')
top.protocol(\"WM_DELETE_WINDOW\", lambda: self.quit(top)) # 点击关闭按钮时跳入quit函数
tree = ttk.Treeview(top, show=\'headings\', column=(\'cid\', \'name\', \'teacher\', \'time\', \'classroom\', \'credit\'))
tree.place(rely=0.37, width=CurWid, relheight=0.6)
tree.column(\'cid\', width=100, anchor=\"center\")
tree.column(\'name\', width=200, anchor=\"center\")
tree.column(\'teacher\', width=100, anchor=\"center\")
tree.column(\'time\', width=150, anchor=\"center\")
tree.column(\'classroom\', width=150, anchor=\"center\")
tree.column(\'credit\', width=50, anchor=\'center\')
tree.heading(\'cid\', text=\'课程号\')
tree.heading(\'name\', text=\'课程名\')
tree.heading(\'teacher\', text=\'老师\')
tree.heading(\'time\', text=\'时间\')
tree.heading(\'classroom\', text=\'教室\')
tree.heading(\'credit\', text=\'学分\')
Label(top, text=\'课程号:\').grid(row=0, column=0, pady=5)
Label(top, text=\'课程名:\').grid(row=1, column=0, pady=5)
Label(top, text=\'老师:\').grid(row=2, column=0, pady=5)
Label(top, text=\'时间:\').grid(row=3, column=0, pady=5)
Label(top, text=\'教室:\').grid(row=4, column=0, pady=5)
Label(top, text=\'学分:\').grid(row=5, column=0, pady=5)
Entry(top, textvariable=self.cid).grid(row=0, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.course_name).grid(row=1, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.teacher).grid(row=2, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.time).grid(row=3, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.classroom).grid(row=4, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.credit).grid(row=5, column=1, pady=5, ipadx=60)
Button(top, text=\'显示所有课程信息\', command=lambda: self.show_course_info(tree)).grid(row=0, column=2, padx=200, ipadx=35)
Button(top, text=\'查询课程信息\', command=lambda: self.search_course_info(tree)).grid(row=1, column=2, padx=200, ipadx=50)
def show_course_info(self, tree):
x = tree.get_children()
for item in x:
tree.delete(item)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
cur.execute(\"select * from course order by cid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item) # END表示插入表格末尾
cur.close()
con.close()
def search_course_info(self, tree):
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sign = 0 # sign=0表示还没有碰到不为空的entry
# 先清除原始数据
x = tree.get_children()
for item in x:
tree.delete(item)
if self.cid.get() != \"\":
sqlname_1 = \"select * from course where cid = %s\"
result = cur.execute(sqlname_1, self.cid.get())
if result < 1:
showerror(title=\'提示\', message=\'未找到相关课程\')
else:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
cur.close()
con.close()
return # 函数结束直接跳出
if self.course_name.get() != \"\":
sqlname_2 = \"select * from course where course_name like \'%%%%%s%%%%\'\"
sqlname_2 = sqlname_2 % (self.course_name.get())
result = cur.execute(sqlname_2)
lst = cur.fetchall()
if result < 1:
showerror(title=\'提示\', message=\'未找到相关课程\')
else:
for item in lst:
tree.insert(\"\", END, values=item)
if self.teacher.get() != \"\":
temp = tree.get_children()
temp_length = 0
for item in temp:
temp_length += 1
if temp_length == 0:
cur.execute(\"select * from course order by cid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
temp_2 = tree.get_children()
for item in temp_2:
# print((tree.item(item, \"values\"))[2])
if (tree.item(item, \"values\"))[2] != self.teacher.get():
tree.delete(item)
temp_length -= 1
if temp_length == 0:
showerror(title=\'提示\', message=\'未找到相关课程\')
if self.time.get() != \"\":
temp = tree.get_children()
temp_length = 0
for item in temp:
temp_length += 1
if temp_length == 0:
cur.execute(\"select * from course order by cid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
temp_2 = tree.get_children()
for item in temp_2:
if (tree.item(item, \"values\"))[3] != self.time.get():
tree.delete(item)
temp_length -= 1
if temp_length == 0:
showerror(title=\'提示\', message=\'未找到相关课程\')
if self.classroom.get() != \"\":
temp = tree.get_children()
temp_length = 0
for item in temp:
temp_length += 1
if temp_length == 0:
cur.execute(\"select * from course order by cid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
temp_2 = tree.get_children()
for item in temp_2:
if (tree.item(item, \"values\"))[4] != self.classroom.get():
tree.delete(item)
temp_length -= 1
if temp_length == 0:
showerror(title=\'提示\', message=\'未找到相关课程\')
if self.credit.get() != \"\":
temp = tree.get_children()
temp_length = 0
for item in temp:
temp_length += 1
if temp_length == 0:
cur.execute(\"select * from course order by cid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
temp_2 = tree.get_children()
for item in temp_2:
if (tree.item(item, \"values\"))[5] != self.credit.get():
tree.delete(item)
temp_length -= 1
if temp_length == 0:
showerror(title=\'提示\', message=\'未找到相关课程\')
if self.cid.get() == \"\" and self.course_name.get() == \"\" and self.teacher.get() == \"\" and self.time.get() == \"\" \\
and self.classroom.get() == \"\" and self.credit.get() == \"\":
showerror(title=\'提示\', message=\'请至少输入一条查询信息\')
con.close()
cur.close()
def course_selection(self): # 学生选课管理
if not self.handle: # 只有handle为False时(代表无该窗口存在)才能执行建立窗口的语句
self.handle = True
top = Toplevel(self.window)
self.window.withdraw()
# 居中显示
ScreenWid, ScreenHei = top.maxsize()
CurWid = 800
CurHeight = 600
cen_x = (ScreenWid - CurWid) / 2
cen_y = (ScreenHei - CurHeight) / 2
size_xy = \'%dx%d+%d+%d\' % (CurWid, CurHeight, cen_x, cen_y)
top.geometry(size_xy)
# ****************
top.title(\'学生选课管理\')
top.protocol(\"WM_DELETE_WINDOW\", lambda: self.quit(top))
tree = ttk.Treeview(top, show=\'headings\', column=(\'sid\', \'stu_name\', \'cid\', \'course_name\'))
tree.place(rely=0.37, width=CurWid, relheight=0.6)
tree.column(\'sid\', width=175, anchor=\"center\")
tree.column(\'stu_name\', width=200, anchor=\"center\")
tree.column(\'cid\', width=175, anchor=\"center\")
tree.column(\'course_name\', width=200, anchor=\"center\")
tree.heading(\'sid\', text=\'学号\')
tree.heading(\'stu_name\', text=\'姓名\')
tree.heading(\'cid\', text=\'课程号\')
tree.heading(\'course_name\', text=\'课程名\')
Label(top, text=\'学号:\').grid(row=0, column=0, pady=5)
Label(top, text=\'姓名:\').grid(row=1, column=0, pady=5)
Label(top, text=\'课程号:\').grid(row=2, column=0, pady=5)
Label(top, text=\'课程名:\').grid(row=3, column=0, pady=5)
Entry(top, textvariable=self.sid).grid(row=0, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.name).grid(row=1, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.cid).grid(row=2, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.course_name).grid(row=3, column=1, pady=5, ipadx=60)
Button(top, text=\'显示所有选课信息\', command=lambda: self.show_selection(tree)).grid(row=0, column=2, padx=200, ipadx=35)
Button(top, text=\'添加选课信息\', command=lambda: self.add_selection(tree)).grid(row=1, column=2, padx=200, ipadx=50)
Button(top, text=\'查询选课信息\', command=lambda: self.search_selection(tree)).grid(row=2, column=2, padx=200, ipadx=50)
Button(top, text=\'删除选课信息\', command=lambda: self.delete_selection(tree)).grid(row=3, column=2, padx=200, ipadx=50)
def show_selection(self, tree):
x = tree.get_children()
for item in x:
tree.delete(item)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
if self.user_handle: # 如果是学生
cur.execute(\"select sid,stu_name,cid,course_name from stu_course where sid = %s\", self.user_name)
lst = cur.fetchall()
else:
cur.execute(\"select sid,stu_name,cid,course_name from stu_course order by sid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item) # END表示插入表格末尾
cur.close()
con.close()
def add_selection(self, tree):
ans = askyesno(title=\'提示\', message=\'是否进行当前操作\')
if ans is True:
if self.sid.get() == \"\" or self.cid.get() == \"\":
showerror(title=\'提示\', message=\'请输入学号与课程号!\')
else:
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
if self.user_handle: # 如果是学生用户
sid = self.user_name
else:
sid = self.sid.get()
name = self.name.get()
cid = self.cid.get()
# 检验(SID,CID)是否已经存在
sqlSearch = \"select * from stu_course where sid = %s and cid = %s\"
result = cur.execute(sqlSearch, (sid, cid))
if result > 0:
showerror(title=\"提示\", message=\"该选课已存在!\")
else: # 此处还要加一个防止时间冲突的语句
cur.execute(\"select time from course where cid = %s\", self.cid.get())
temp_time = cur.fetchone()
temp_result = cur.execute(\"select time,course_name from stu_course natural join course where\"
\" sid = %s and time = %s\", (self.sid.get(), temp_time))
if temp_result > 0:
lst = cur.fetchone()
showerror(title=\'提示\', message=\"选课时间与%s冲突\" % lst[1])
return
# cur.execute(\"select \")
cur.execute(\"select sid,name from stu_info where sid = %s\", (self.sid.get()))
temp_stu = cur.fetchone()
cur.execute(\"select cid,course_name from course where cid = %s\", (self.cid.get()))
temp_course = cur.fetchone()
# print(temp_stu[0], temp_stu[1], temp_course[0], temp_course[1])
sql_2 = \"insert into stu_course values(%s,%s,%s,%s,NULL)\"
result = cur.execute(sql_2, (temp_stu[0], temp_stu[1], temp_course[0], temp_course[1]))
if result > 0:
con.commit()
showinfo(title=\"提示\", message=\"添加成功!\")
tree.insert(\"\", END, values=(temp_stu[0], temp_stu[1], temp_course[0], temp_course[1]))
else:
showerror(title=\'提示\', message=\'添加失败!\')
cur.close()
con.close()
def search_selection(self, tree):
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
# 先清除原始数据
x = tree.get_children()
for item in x:
tree.delete(item)
if self.user_handle:
if self.cid.get() != \"\":
sql = \"select sid,stu_name,cid,course_name from stu_course where sid = %s and cid = %s\"
result = cur.execute(sql, (self.user_name, self.cid.get()))
if result == 0:
showerror(title=\'提示\', message=\'未找到相关选课信息!\')
else:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
return
sign = False # false代表表格中还没有信息
if self.sid.get() == \"\" and self.cid.get() == \"\":
showerror(title=\'提示\', message=\'请输入完整信息!\')
if self.sid.get() != \"\":
sql = \"select sid,stu_name,cid,course_name from stu_course where sid = %s order by cid\"
result = cur.execute(sql, self.sid.get())
if result == 0:
showerror(title=\'提示\', message=\'未找到相关选课信息!\')
return
else:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
sign = True
if self.cid.get() != \"\":
if not sign:
sql = \"select sid,stu_name,cid,course_name from stu_course where cid = %s order by sid\"
result = cur.execute(sql, self.cid.get())
if result == 0:
showerror(title=\'提示\', message=\'未找到相关选课信息!\')
# return
else:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item)
else:
x = tree.get_children()
for item in x:
if (tree.item(item, \"values\"))[2] != self.cid.get():
tree.delete(item)
con.close()
cur.close()
def delete_selection(self, tree):
ans = askyesno(title=\'提示\', message=\'是否进行当前操作\')
if ans is True:
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
if self.sid.get() == \"\" or self.cid.get() == \"\":
showerror(title=\'提示\', message=\'请输入完整信息!\')
else:
result = cur.execute(\"delete from stu_course where sid = %s and cid = %s\", (self.sid.get(), self.cid.get()))
if result == 0:
showerror(title=\'提示\', message=\'删除失败!\')
else:
x = tree.get_children()
for item in x:
if (tree.item(item, \"values\"))[0] == self.sid.get() \\
and (tree.item(item, \"values\"))[2] == self.cid.get():
tree.delete(item)
con.commit()
con.close()
cur.close()
def exam(self): # 考试管理(登记分数)
if not self.handle: # 只有handle为False时(代表无该窗口存在)才能执行建立窗口的语句
self.handle = True
top = Toplevel(self.window)
self.window.withdraw()
# 居中显示
ScreenWid, ScreenHei = top.maxsize()
CurWid = 800
CurHeight = 600
cen_x = (ScreenWid - CurWid) / 2
cen_y = (ScreenHei - CurHeight) / 2
size_xy = \'%dx%d+%d+%d\' % (CurWid, CurHeight, cen_x, cen_y)
top.geometry(size_xy)
# ****************
top.title(\'考试管理\')
top.protocol(\"WM_DELETE_WINDOW\", lambda: self.quit(top))
tree = ttk.Treeview(top, show=\'headings\', column=(\'sid\', \'stu_name\', \'cid\', \'course_name\', \'score\'))
tree.place(rely=0.37, width=CurWid, relheight=0.6)
tree.column(\'sid\', width=150, anchor=\"center\")
tree.column(\'stu_name\', width=200, anchor=\"center\")
tree.column(\'cid\', width=150, anchor=\"center\")
tree.column(\'course_name\', width=200, anchor=\"center\")
tree.column(\'score\', width=50, anchor=\"center\")
tree.heading(\'sid\', text=\'学号\')
tree.heading(\'stu_name\', text=\'姓名\')
tree.heading(\'cid\', text=\'课程号\')
tree.heading(\'course_name\', text=\'课程名\')
tree.heading(\'score\', text=\'成绩\')
Label(top, text=\'学号:\').grid(row=0, column=0, pady=5)
Label(top, text=\'姓名:\').grid(row=1, column=0, pady=5)
Label(top, text=\'课程号:\').grid(row=2, column=0, pady=5)
Label(top, text=\'课程名:\').grid(row=3, column=0, pady=5)
Label(top, text=\'成绩:\').grid(row=4, column=0, pady=5)
Entry(top, textvariable=self.sid).grid(row=0, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.name).grid(row=1, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.cid).grid(row=2, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.course_name).grid(row=3, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.score).grid(row=4, column=1, pady=5, ipadx=60)
Button(top, text=\'显示所有成绩信息\', command=lambda: self.show_exam(tree)).grid(row=0, column=2, padx=200,
ipadx=35)
Button(top, text=\'更新学生成绩\', command=lambda: self.update_score(tree)).grid(row=1, column=2, padx=200,
ipadx=50)
Button(top, text=\'查询成绩信息\', command=lambda: self.search_exam(tree)).grid(row=2, column=2, padx=200,
ipadx=50)
Button(top, text=\'查看表中及格信息\', command=lambda: self.pass_score(tree)).grid(row=3, column=2, padx=200,
ipadx=35)
Button(top, text=\'查看表中挂科信息\', command=lambda: self.fail_score(tree)).grid(row=4, column=2, padx=200,
ipadx=35)
def show_exam(self, tree):
x = tree.get_children()
for item in x:
tree.delete(item)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
if self.user_handle: # 如果是学生则退出
cur.execute(\"select * from stu_course where sid = %s\",self.user_name)
else:
cur.execute(\"select * from stu_course order by sid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item) # END表示插入表格末尾
cur.close()
con.close()
def update_score(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
ans = askyesno(title=\'提示\', message=\'是否进行当前操作\\n(注意:只有成绩为空或有误时才可更新)\')
if ans is True:
if self.sid.get() == \"\" or self.cid.get() == \"\" or self.score.get() == \"\":
showerror(title=\'提示\', message=\'请输入完整信息\')
return
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sql = \"update stu_course set score = %s where sid = %s and cid = %s\"
result = cur.execute(sql, (self.score.get(), self.sid.get(), self.cid.get()))
if result == 0:
showerror(title=\'提示\', message=\'更新失败!\')
else:
if float(self.score.get()) >= 60:
cur.execute(\"delete from exam_makeup where sid = %s and cid = %s\", (self.sid.get(), self.cid.get()))
con.commit()
showinfo(title=\'提示\', message=\'更新成功!\')
self.show_exam(tree)
cur.close()
con.close()
def search_exam(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
x = tree.get_children()
for item in x:
tree.delete(item)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
if self.cid.get() != \"\" and self.sid.get() != \"\":
sql = \"select * from stu_course where sid = %s and cid = %s\"
result = cur.execute(sql, (self.sid.get(), self.cid.get()))
if result == 0:
showerror(title=\'提示\', message=\'未找到相关信息\')
else:
lst = cur.fetchone()
tree.insert(\"\", END, value=lst)
else:
if self.sid.get() != \"\":
result = cur.execute(\"select * from stu_course where sid = %s\", self.sid.get())
if result > 0:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, value=item)
else:
showerror(title=\'提示\', message=\'未找到相关信息\')
if self.name.get() != \"\":
temp = 0
x = tree.get_children()
for item in x:
temp += 1
if temp == 0: # 代表当前表格中没有数据
result = cur.execute(\"select * from stu_course where stu_name like \'%%%%%s%%%%\'\" % (self.name.get()))
if result > 0:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, value=item)
else:
showerror(title=\'提示\', message=\'未找到相关信息\')
else:
for item in x:
if self.name.get() not in (tree.item(item, \"values\"))[1]:
tree.delete(item)
# print(\"deleting......\")
if self.cid.get() != \"\":
temp = 0
x = tree.get_children()
for item in x:
temp += 1
if temp == 0: # 代表当前表格中没有数据
result = cur.execute(\"select * from stu_course where cid = %s\", self.cid.get())
if result > 0:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, value=item)
else:
showerror(title=\'提示\', message=\'未找到相关信息\')
else:
for item in x:
if self.cid.get() != (tree.item(item, \"values\"))[2]:
tree.delete(item)
if self.course_name.get() != \"\":
temp = 0
x = tree.get_children()
for item in x:
temp += 1
if temp == 0: # 代表当前表格中没有数据
result = cur.execute(
\"select * from stu_course where course_name like \'%%%%%s%%%%\'\" % (self.course_name.get()))
if result > 0:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, value=item)
else:
showerror(title=\'提示\', message=\'未找到相关信息\')
else:
for item in x:
if self.course_name.get() not in (tree.item(item, \"values\"))[3]:
tree.delete(item)
if self.score.get() != \"\":
temp = 0
x = tree.get_children()
for item in x:
temp += 1
if temp == 0: # 代表当前表格中没有数据
# print(float(self.score.get()))
result = cur.execute(\"select * from stu_course where score = %s\", self.score.get())
if result > 0:
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, value=item)
else:
showerror(title=\'提示\', message=\'未找到相关信息\')
else:
for item in x:
if (tree.item(item, \"values\"))[4] == \"None\":
tree.delete(item)
else:
if float(self.score.get()) != float((tree.item(item, \"values\"))[4]):
tree.delete(item)
con.close()
cur.close()
# 只留下表格中不及格的信息
def fail_score(self, tree):
x = tree.get_children()
for item in x:
if(tree.item(item, \"values\"))[4] == \"None\":
tree.delete(item)
else:
if float((tree.item(item, \"values\"))[4]) >= 60:
tree.delete(item)
def pass_score(self, tree):
x = tree.get_children()
for item in x:
if (tree.item(item, \"values\"))[4] == \"None\":
tree.delete(item)
else:
if float((tree.item(item, \"values\"))[4]) < 60:
tree.delete(item)
def modify_exam(self, tree):
pass
def exam_makeup(self): # 补考重修
if not self.handle: # 只有handle为False时(代表无该窗口存在)才能执行建立窗口的语句
self.handle = True
top = Toplevel(self.window)
self.window.withdraw()
# 居中显示
ScreenWid, ScreenHei = top.maxsize()
CurWid = 800
CurHeight = 600
cen_x = (ScreenWid - CurWid) / 2
cen_y = (ScreenHei - CurHeight) / 2
size_xy = \'%dx%d+%d+%d\' % (CurWid, CurHeight, cen_x, cen_y)
top.geometry(size_xy)
# ****************
top.title(\'补考重修\')
top.protocol(\"WM_DELETE_WINDOW\", lambda: self.quit(top))
tree = ttk.Treeview(top, show=\'headings\', column=(\'sid\', \'stu_name\', \'cid\', \'course_name\', \'score\'))
tree.place(rely=0.37, width=CurWid, relheight=0.6)
tree.column(\'sid\', width=150, anchor=\"center\")
tree.column(\'stu_name\', width=200, anchor=\"center\")
tree.column(\'cid\', width=150, anchor=\"center\")
tree.column(\'course_name\', width=200, anchor=\"center\")
tree.column(\'score\', width=50, anchor=\"center\")
tree.heading(\'sid\', text=\'学号\')
tree.heading(\'stu_name\', text=\'姓名\')
tree.heading(\'cid\', text=\'课程号\')
tree.heading(\'course_name\', text=\'课程名\')
tree.heading(\'score\', text=\'成绩\')
Label(top, text=\'学号:\').grid(row=0, column=0, pady=5)
Label(top, text=\'姓名:\').grid(row=1, column=0, pady=5)
Label(top, text=\'课程号:\').grid(row=2, column=0, pady=5)
Label(top, text=\'课程名:\').grid(row=3, column=0, pady=5)
Label(top, text=\'成绩:\').grid(row=4, column=0, pady=5)
Entry(top, textvariable=self.sid).grid(row=0, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.name).grid(row=1, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.cid).grid(row=2, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.course_name).grid(row=3, column=1, pady=5, ipadx=60)
Entry(top, textvariable=self.score).grid(row=4, column=1, pady=5, ipadx=60)
Button(top, text=\'显示所有成绩信息\', command=lambda: self.show_exam_makeup(tree)).grid(row=0, column=2, padx=200,
ipadx=35)
Button(top, text=\'更新学生成绩\', command=lambda: self.update_exam_makeup(tree)).grid(row=1, column=2, padx=200,
ipadx=50)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
cur.execute(\"insert into exam_makeup (sid,stu_name,cid,course_name) \"
\"select distinct sid,stu_name,cid,course_name from stu_course \"
\"where score < 60 and not exists (select * from exam_makeup)\")
con.commit()
con.close()
cur.close()
def show_exam_makeup(self, tree):
x = tree.get_children()
for item in x:
tree.delete(item)
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
if self.user_handle: # 如果是学生则退出
cur.execute(\"select * from exam_makeup where sid = %s\",self.user_name)
else:
cur.execute(\"select * from exam_makeup order by sid\")
lst = cur.fetchall()
for item in lst:
tree.insert(\"\", END, values=item) # END表示插入表格末尾
cur.close()
con.close()
def update_exam_makeup(self, tree):
if self.user_handle: # 如果是学生则退出
showinfo(title=\'提示\', message=\'您没有操作权限\')
return
ans = askyesno(title=\'提示\', message=\'是否进行当前操作\')
if ans is True:
if self.sid.get() == \"\" or self.cid.get() == \"\" or self.score.get() == \"\":
showerror(title=\'提示\', message=\'请输入完整信息\')
return
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
sql = \"update exam_makeup set score = %s where sid = %s and cid = %s\"
result = cur.execute(sql, (self.score.get(), self.sid.get(), self.cid.get()))
if result == 0:
showerror(title=\'提示\', message=\'更新失败!\')
else:
# 补考过了最终在stu_course中只能改为60
sql_2 = \"update stu_course set score = 60 where sid = %s and cid = %s\"
result_2 = cur.execute(sql_2, (self.sid.get(), self.cid.get()))
if result_2 == 0:
showerror(title=\'提示\', message=\'更新失败!\')
else:
con.commit()
showinfo(title=\'提示\', message=\'更新成功!\')
self.show_exam_makeup(tree)
cur.close()
con.close()
main.py:
import tkinter as tk
from tkinter import messagebox
from PIL import Image, ImageTk
import pymysql
# https://tkdocs.com/tutorial/index.html tk说明文档
from menu import menu
con = pymysql.connect(user=\'root\', password=\'123\', database=\'student\', charset=\'utf8\')
cur = con.cursor()
# 如果是 from tkinter import * 就不需要加前缀tk
window = tk.Tk()
# window.iconbitmap(default=r\'pic.gif\') # 这种方法只能应用ico格式的图片
# window.iconphoto(False,tk.PhotoImage(file=\'smile.png\')) #这个样子不能使用jpg
window.iconphoto(False, ImageTk.PhotoImage(file=\'icon1.png\')) # False代表他的子窗口不可以使用 #这样写好处在于可以用所有的图片格式
window.title(\'学生选课管理系统\')
window.geometry(\'450x300\')
# welcome image
# 参考博客 https://www.cnblogs.com/shwee/p/9427975.html#D12
im_root = Image.open(\'nature.jpg\').resize((450, 300))
img= ImageTk.PhotoImage(im_root)
imLabel = tk.Label(window, image=img).pack()
# canvas = tk.Canvas(window, height=450, width=300)
# image_file = tk.PhotoImage(file=\'pic.gif\')
# canvas.create_image(400,300,image=im_root)
# canvas.pack()
# user information
tk.Label(window, text=\'User name:\').place(relx=0.1,rely=0.5)
tk.Label(window, text=\'Password:\').place(relx=0.1,rely=0.62)
# var_user_name=tk.StringVar()
# entry_user_name=tk.Entry(window,textvariable = var_user_name)
entry_user_name = tk.Entry(window)
var_user_name = entry_user_name.get()
entry_user_name.place(relx=0.31, rely=0.5)
# another method
entry_user_pwd = tk.Entry(window, show=\'*\') # show=\'*\'令密码输入显示为*
entry_user_pwd.place(relx=0.31, rely=0.62)
var_user_pwd = entry_user_pwd.get()
def usr_login():
user_name = entry_user_name.get() # 为啥不能直接用var_user_name跟var_user_pwd???
user_pwd = entry_user_pwd.get()
if user_name == \'admin\' and user_pwd == \'123\':
# window.destroy()#quit跟destory
messagebox.showinfo(title=\'Welcome\', message=\'How are you?\')
window.destroy()
root = tk.Tk()
menu(root, False)
else:
result = cur.execute(\"select * from user_info where user_name = %s and password = %s\", (user_name, user_pwd))
if result > 0:
messagebox.showinfo(title=\'Welcome\', message=\'How are you?\')
window.destroy()
root = tk.Tk()
menu(root, True, user_name)
def usr_register():
name = entry_user_name.get()
pwd = entry_user_pwd.get()
if name != \"\" and pwd != \"\":
result = cur.execute(\"select * from user_info where user_name = %s\", name)
if result > 0:
messagebox.showerror(title=\'提示\', message=\'用户已存在\')
else:
result_2 = cur.execute(\"select * from stu_info where sid = %s\", name)
if result_2 == 0:
messagebox.showerror(title=\'提示\', message=\'您不是该学校学生,请输入您的学号进行注册\')
else:
cur.execute(\"insert into user_info values(%s,%s)\", (name, pwd))
con.commit()
btn_login = tk.Button(window, text=\'Login\', command=usr_login)
btn_login.place(relx=0.3, rely=0.8) # relx/rely是相对位置,取值范围0~1
btn_register = tk.Button(window, text=\'Register\', command=usr_register)
btn_register.place(relx=0.6, rely=0.8)
# con.close()
# cur.close()
window.mainloop()
用到的图片可以自行修改。