基于Python下Tkinter实现学生选课管理系统

        本题为数据库的一项课程作业,结合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()

用到的图片可以自行修改。

你可能感兴趣的:(python,开发语言)