选题:学生信息管理系统

项目介绍:

       这个项目主要包含了UI界面和后台程序,该项目是通过文件存储的方式来保存学生信息的,主要包含的操作有学生信息的增删改查功能,还有用户的登录功能,涵盖的信息有学生的学号 姓名 性别 年龄 学院 专业,涉及的课程内容有GUI界面,类和对象,方法,字典,列表,文件操作,获取异常等。

        登录,通过输入管理员的账号密码来实现登录操作。具体实现的过程是通过输入框输入账号密码,然后使用get方法来获取各个输入框的值,再用if语句判断获取的值是否等于自己设置的账号密码,如果相等,则登录成功,进入主界面。

       添加学生信息,通过输入学生的个人信息,即学号、姓名、年龄、学院、专业,来实现添加学生的操作。具体实现的过程是用户通过输入框输入学号、姓名、年龄、学院、专业,然后使用get方法来获取各个输入框的内容,判断学号是否重复,如果学号不重复,则把信息赋值到列表中,然后通过列表的形式把值赋给字典,最后把列表写入文件。

       删除学生信息,通过输入学生的学号来实现删除学生的操作。具体实现的过程是用户通过输入框输入学号,然后通过get方法来获取输入框的学号;再读取文件,把文件转换成字典的方式,通过字典的键值对来判断学号是否存在,如果存在则把用户输入信息的匹配数据所在行删除。

       修改学生信息,通过输入学生的学号来实现对学生信息的修改。具体实现的过程是用户通过输入框输入学号,然后通过get方法来获取输入框的学号;打开文件并读取文件中的内容,将内容转换为字典的格式,检查字典中是否存在该学号;如果存在则进入修改页面,输入信息到输入框,通过get方法获取输入框的学号,然后通过键值对的方法来写入字典,最后保存到文件中。

       查询学生信息,通过输入学生的学号来实现对学生信息的查询。具体实现的过程是用户通过输入框输入学号,然后通过get方法来获取输入框的学号;打开文件并读取文件中的内容,将内容转换为字典的格式,检查字典是否存在该学号;如果存在,则通过表格的方式来输出信息,最后输出该学生信息,显示在页面。

       显示所有学生信息,具体实现的过程是通过读取文件内容,通过total方法统计并输出汇总人数,然后通过表格的方式来定义表头和内容格式,最后把所有学生信息全部有序地显示在表格上。

退出,点击退出或者Esc键,再点击“是”退出程序。

流程图:

python学生管理系统报告 学生管理系统python tkinter_python学生管理系统报告

自述:

学生信息管理系统是比较普通的题材,因为本人基础不扎实,所以选择了这一题材,在实验的过程中,遇到的问题比较多,也比较难解决,有时候一个问题要几天才能解决,甚至根本解决不了,这个时候还要请求老师的帮忙,这些天来还得感谢老师的帮忙,我才能完整的完成这个项目。

刚开始做这个项目,并没有百分百的把握,因为之前自学过一点python,发现太难就没有学下去的动力,但是项目做到一半,发现python还是挺有趣的一门语言。

本来刚开始是只做了主界面,没有登录界面的,但是听了老师的建议之后,还是加了登录界面进去,然后发现有了登录界面的话,看起来好很多。

最主要的问题就是调试,因为调试的过程真的非常不容易,需要使用print语句和断点的方法来对程序进行细心并且耐心地调试,有时候if,for,while,try catch语句混合起来太多就会出现异常报错,或者出现逻辑上的问题,而导致某个功能出现较严重的问题,甚至有时候只是因为一个小小的break没有添加或者缩进多一个或少一个就出现了大问题。

       后期可以增加用户二次确认提示,主界面时间显示,完善显示所有学生信息界面的格式,以及增加用户注册功能等。

个人观点:

优点:

       系统功能齐全,界面简洁美观,操作简单。

缺点:

       整体代码冗余量较大,功能少,细节问题处理不到位,如删除没有给予二次确认,修改操作点击X会出现大问题,也就是可能导致后台数据清空或者删除该学生,还有就是基本没有使用到类这个知识点,而且登录页面没有注册功能,只能在代码中设置账号密码,界面不够好看等问题。

截图:

python学生管理系统报告 学生管理系统python tkinter_python学生管理系统报告_02

python学生管理系统报告 学生管理系统python tkinter_python_03

python学生管理系统报告 学生管理系统python tkinter_get方法_04

python学生管理系统报告 学生管理系统python tkinter_python_05

python学生管理系统报告 学生管理系统python tkinter_读取文件_06

python学生管理系统报告 学生管理系统python tkinter_读取文件_07

python学生管理系统报告 学生管理系统python tkinter_get方法_08

python学生管理系统报告 学生管理系统python tkinter_get方法_09

python学生管理系统报告 学生管理系统python tkinter_get方法_10

python学生管理系统报告 学生管理系统python tkinter_python_11

文件结构:

python学生管理系统报告 学生管理系统python tkinter_读取文件_12

代码如下

 Stu_demo.py

import os
from tkinter import *
from tkinter import ttk
from tkinter.messagebox import showerror, showinfo, askquestion

import Class

# 引用类和对象
s = Class.Save_txt
cen = Class.Center
filename = '../DB_stu/student.txt'  # 文件名


# 添加界面
def add():
    add_tk = Tk()
    add_tk.title('')
    cen.show_center(add_tk)
    add_tk.resizable(False, False)  # 不可调整大小
    add_tk.iconphoto(False, PhotoImage(file="../image/stu.png"))
    add_word = Label(add_tk, text='添加学生信息', font=('华文新魏', 20))
    add_word.place(relx=0.3, rely=0.05, relwidth=0.4, relheight=0.05)

    # 字样
    no_label = Label(add_tk, text='学号')
    name_label = Label(add_tk, text='姓名')
    sex_label = Label(add_tk, text='性别')
    age_label = Label(add_tk, text='年龄')
    academy_label = Label(add_tk, text='学院')
    major_label = Label(add_tk, text='专业')
    no_label.place(relx=0.165, rely=0.17, relwidth=0.2, relheight=0.05)
    name_label.place(relx=0.165, rely=0.27, relwidth=0.2, relheight=0.05)
    sex_label.place(relx=0.165, rely=0.37, relwidth=0.2, relheight=0.05)
    age_label.place(relx=0.165, rely=0.47, relwidth=0.2, relheight=0.05)
    academy_label.place(relx=0.165, rely=0.57, relwidth=0.2, relheight=0.05)
    major_label.place(relx=0.165, rely=0.67, relwidth=0.2, relheight=0.05)

    no = StringVar()
    name = StringVar()
    sex = StringVar()
    age = IntVar()
    academy = StringVar()
    major = StringVar()

    # 输入框
    no_input = ttk.Entry(add_tk, textvariable=no, font=('Microsoft yahei', 10))
    name_input = ttk.Entry(add_tk, textvariable=name, font=('Microsoft yahei', 10))
    sex_input1 = ttk.Radiobutton(add_tk, text='男', variable=sex, value='男')
    sex_input2 = ttk.Radiobutton(add_tk, text='女', variable=sex, value='女')
    age_input = ttk.Entry(add_tk, textvariable=age, font=('Microsoft yahei', 10))
    age_input.delete(0, 'end')  # 去除默认值 0
    academy_values = ['法学院', '会计学院', '外国语学院', '管理学院', '经济学院', '艺术设计学院', '现代信息产业学院',
                      '信息技术与工程学院', '国际学院']
    academy_input = ttk.Combobox(add_tk, textvariable=academy, values=academy_values, font=('Microsoft yahei', 10))
    major_input = ttk.Entry(add_tk, textvariable=major, font=('Microsoft yahei', 10))

    no_input.place(relx=0.335, rely=0.17, relwidth=0.4, relheight=0.05)
    name_input.place(relx=0.335, rely=0.27, relwidth=0.4, relheight=0.05)
    sex_input1.place(relx=0.335, rely=0.37)
    sex_input2.place(relx=0.435, rely=0.37)
    age_input.place(relx=0.335, rely=0.47, relwidth=0.4, relheight=0.05)
    academy_input.place(relx=0.335, rely=0.57, relwidth=0.4, relheight=0.05)
    major_input.place(relx=0.335, rely=0.67, relwidth=0.4, relheight=0.05)

    # 返回按钮
    back_btn = Button(add_tk, text='返回', bg='gainsboro', activebackground='gainsboro', relief=GROOVE,
                      command=lambda: [add_tk.destroy(), main()])
    back_btn.place(relx=0.2, rely=0.8, relwidth=0.15, relheight=0.05)

    # 将信息写入文件
    def add_data():
        stu_if_dict = {}
        student_no = no.get()
        student_name = name.get()
        student_sex = sex.get()
        student_age = age.get()
        student_academy = academy.get()
        student_major = major.get()
        # print(student_no, student_name, student_sex, student_age, student_academy, student_major)

        # a+ 以附加读写方式打开
        f = open(filename, 'a+', encoding='utf-8')
        f.readlines()

        # r只读 防止后面追加信息
        # 获取异常防止文件不存在
        try:
            w_file = open(filename, 'r', encoding='utf-8')
            stu_file = w_file.readlines()
            for item in stu_file:
                stu_if_dict = dict(eval(item))
                # print(stu_if_dict)
        except FileNotFoundError:  # 文件不存在
            # 字典赋空
            stu_if_dict = []

        if stu_if_dict["学号"] != student_no:
            # stu_if_dict["学号"] == student_no
            # print("====" + stu_if_dict["学号"])
            # 对输入内容限制
            if len(student_no) != 0 and len(student_name) != 0 and len(student_sex) != 0 and \
                    student_age != '' and len(student_academy) != 0 and len(student_major) != 0:
                print('学号:' + student_no)
                print('姓名:' + student_name)
                print('性别:' + student_sex)
                print(f'年龄:{student_age}')
                print('学院:' + student_academy)
                print('专业:' + student_major)

                # 将录入的学生信息保存到字典当中
                student = {'学号': student_no, '姓名': student_name, '性别': student_sex, '年龄': student_age,
                           '学院': student_academy, '专业': student_major}
                # print(student)
                # 将字典添加到列表中
                student_list = [student]
                # 保存到文件
                s.save(student_list)

                showinfo(title='提示', message='添加成功!')
            else:
                showinfo(title='提示', message='请输入信息!')
        else:
            showerror(title='提示', message='该学号已存在!')
        # print('添加失败!')

    # 保存按钮
    save_btn = Button(add_tk, text='保存', bg='lightskyblue', activebackground='lightskyblue', relief=GROOVE,
                      command=lambda: [add_data(), add_tk.destroy(), main()])
    save_btn.place(relx=0.65, rely=0.8, relwidth=0.15, relheight=0.05)


# 删除界面
def delete():
    delete_tk = Tk()
    delete_tk.title('')
    cen.show_center(delete_tk)
    delete_tk.resizable(False, False)
    delete_tk.iconphoto(False, PhotoImage(file="../image/stu.png"))
    delete_word = Label(delete_tk, text='删除学生信息', font=('华文新魏', 20))
    delete_word.place(relx=0.3, rely=0.1, relwidth=0.4, relheight=0.05)
    delete_label = Label(text='请输入你要删除的学生学号:', font=('黑体', 13))
    delete_label.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.1)

    no = StringVar()

    # 输入框
    no_input = ttk.Entry(delete_tk, textvariable=no, font=('Microsoft yahei', 10))
    no_input.place(relx=0.3, rely=0.4, relwidth=0.4, relheight=0.05)

    # 返回按钮
    back_btn = Button(delete_tk, text='返回', bg='gainsboro', activebackground='gainsboro', relief=GROOVE,
                      command=lambda: [delete_tk.destroy(), main()])
    back_btn.place(relx=0.2, rely=0.8, relwidth=0.15, relheight=0.05)

    # 将文件中的所在行信息删除
    def del_info():
        student_no = no.get()
        # print(student_no)
        if len(student_no) != 0:
            if os.path.exists(filename):
                file = open(filename, 'r', encoding='utf-8')
                student_old = file.readlines()
            else:
                # 赋空列表
                student_old = []
            flag = False  # 标记是否删除
            if student_old:
                w_file = open(filename, 'w', encoding='utf-8')
                d = {}
                for item in student_old:
                    d = dict(eval(item))  # 将字符串转成字典
                    if d['学号'] != student_no:
                        w_file.write(str(d) + '\n')
                    else:
                        flag = True
                if flag:
                    print(f"学号为{student_no}的学生已被删除!")
                    showinfo(title='提示', message='删除成功!')
                else:
                    showerror(title='提示', message='没有找到该学号的学生信息!')
            else:
                # print('无学生信息!')
                showerror(title='提示', message='后台无数据!')
        elif len(student_no) == 0:
            showinfo(title='提示', message='请输入学号!')

    # # 删除二次确认
    # def delete_if():
    #     delete_result = askquestion(title='警告', message="确认删除?")
    #     # print('askquestion: %s'.rjust(18) % delete_result)  # 查看返回值
    #     if delete_result == "yes":
    #         del_info()
    #     else:
    #         pass

    # 删除按钮
    delete_btn = Button(delete_tk, text='删除', bg='lightskyblue', activebackground='lightskyblue', relief=GROOVE,
                        command=lambda: [del_info(), delete_tk.destroy(), main()])
    delete_btn.place(relx=0.65, rely=0.8, relwidth=0.15, relheight=0.05)


# 修改界面
def revise():
    revise_tk = Tk()
    revise_tk.title('')
    cen.show_center(revise_tk)
    revise_tk.resizable(False, False)
    revise_tk.iconphoto(False, PhotoImage(file="../image/stu.png"))
    revise_word = Label(revise_tk, text='修改学生信息', font=('华文新魏', 20))
    revise_word.place(relx=0.3, rely=0.1, relwidth=0.4, relheight=0.05)
    revise_label = Label(revise_tk, text='请输入你要修改的学生学号:', font=('黑体', 13))
    revise_label.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.1)

    no = StringVar()

    # 输入框
    no_input = ttk.Entry(revise_tk, textvariable=no, font=('Microsoft yahei', 10))
    no_input.place(relx=0.3, rely=0.4, relwidth=0.4, relheight=0.05)

    # 返回按钮
    back_btn = Button(revise_tk, text='返回', bg='gainsboro', activebackground='gainsboro', relief=GROOVE,
                      command=lambda: [revise_tk.destroy(), main()])
    back_btn.place(relx=0.2, rely=0.8, relwidth=0.15, relheight=0.05)

    def modify():
        student_no = no.get()
        if len(student_no) == 0:
            showinfo(title='提示', message='请输入学号!')
        # print(student_no)
        if os.path.exists(filename):
            rfile = open(filename, 'r', encoding='utf-8')
            student_old = rfile.readlines()
            # 获取文件全部内容
            # file_obj = open(filename, encoding='utf-8')
            # file_contents = file_obj.read()
            # print(file_contents.rstrip())
        else:
            return

        w_file = open(filename, 'w', encoding='utf-8')
        for item in student_old:
            d = dict(eval(item))
            if d['学号'] == student_no:
                # print('找到该学号的学生信息!')
                # print(d["学号"], d["姓名"], d["性别"], d["年龄"], d["学院"], d["专业"])
                while True:
                    try:
                        revise_word.place(relx=0.3, rely=0.05, relwidth=0.4, relheight=0.05)
                        back_btn.destroy()
                        sure_btn.destroy()
                        no_input.destroy()
                        revise_label.destroy()

                        name_label = Label(text='姓名')
                        sex_label = Label(text='性别')
                        age_label = Label(text='年龄')
                        academy_label = Label(text='学院')
                        major_label = Label(text='专业')
                        name_label.place(relx=0.165, rely=0.17, relwidth=0.2, relheight=0.05)
                        sex_label.place(relx=0.165, rely=0.27, relwidth=0.2, relheight=0.05)
                        age_label.place(relx=0.165, rely=0.37, relwidth=0.2, relheight=0.05)
                        academy_label.place(relx=0.165, rely=0.47, relwidth=0.2, relheight=0.05)
                        major_label.place(relx=0.165, rely=0.57, relwidth=0.2, relheight=0.05)

                        name = StringVar()
                        age = IntVar()
                        sex = StringVar()
                        academy = StringVar()
                        major = StringVar()

                        # 输入框
                        name_input = ttk.Entry(revise_tk, textvariable=name, font=('Microsoft yahei', 10))
                        sex_input1 = ttk.Radiobutton(revise_tk, text='男', variable=sex, value='男')
                        sex_input2 = ttk.Radiobutton(revise_tk, text='女', variable=sex, value='女')
                        age_input = ttk.Entry(revise_tk, textvariable=age, font=('Microsoft yahei', 10))
                        age_input.delete(0, 'end')  # 去除默认值 0
                        academy_values = ['法学院', '会计学院', '外国语学院', '管理学院', '艺术设计学院',
                                          '现代信息产业学院', '信息技术与工程学院', '国际学院']
                        academy_input = ttk.Combobox(revise_tk, textvariable=academy, values=academy_values,
                                                     font=('Microsoft yahei', 10))
                        major_input = ttk.Entry(revise_tk, textvariable=major, font=('Microsoft yahei', 10))
                        name_input.place(relx=0.335, rely=0.17, relwidth=0.4, relheight=0.05)
                        sex_input1.place(relx=0.335, rely=0.27)
                        sex_input2.place(relx=0.435, rely=0.27)
                        age_input.place(relx=0.335, rely=0.37, relwidth=0.4, relheight=0.05)
                        academy_input.place(relx=0.335, rely=0.47, relwidth=0.4, relheight=0.05)
                        major_input.place(relx=0.335, rely=0.57, relwidth=0.4, relheight=0.05)

                        name_input.insert(INSERT, d["姓名"])
                        if d["性别"] == "男":
                            sex.set('男')
                        elif d["性别"] == "女":
                            sex.set('女')
                        else:
                            pass
                        age_input.insert(INSERT, d["年龄"])
                        academy_input.insert(INSERT, d["学院"])
                        major_input.insert(INSERT, d["专业"])

                        # print('------------------')
                        # print(name_input)
                        # print(age_input)
                        # print('------------------')

                        # 写入文件
                        def modify_to():
                            student_name = name.get()
                            student_sex = sex.get()
                            student_age = age.get()
                            student_academy = academy.get()
                            student_major = major.get()

                            # print("===" + student_name)
                            # print("===" + student_sex)
                            # print("===" + student_age)
                            # print("===" + student_academy)
                            # print("===" + student_major)

                            # print(len(student_name), len(student_sex), len(student_age), len(student_academy), len(student_major))
                            # 所有输入框不能为空

                            # 'Key': Value
                            d['学号'] = student_no
                            d['姓名'] = student_name
                            d['性别'] = student_sex
                            d['年龄'] = student_age
                            d['学院'] = student_academy
                            d['专业'] = student_major

                            w_file.write(str(d) + '\n')
                            if w_file is not None:
                                w_file.close()
                            # print('修改成功!!!')
                            showinfo(title='提示', message='修改成功!')

                        tip_label = Label(revise_tk, text='Tip: 请勿关闭该窗口,否则将删除该学生信息!!!',
                                          foreground='red')
                        tip_label.place(relx=0.29, rely=0.67, relwidth=0.42, relheight=0.05)
                        # 修改按钮
                        modify_btn = Button(revise_tk, text='修改', bg='lightskyblue',
                                            activebackground='lightskyblue', relief=GROOVE,
                                            command=lambda: [modify_to(), revise_tk.destroy(), main()])
                        modify_btn.place(relx=0.4, rely=0.8, relwidth=0.2, relheight=0.05)

                    except IOError:
                        showerror(title='错误', message='您的输入有误,请重新输入!!!')
                        # print('您的输入有误,请重新输入!!!')
                    else:
                        break

            else:
                # print("OK")
                w_file.write(str(d) + '\n')
                # break

    # 确定按钮
    sure_btn = Button(revise_tk, text='确定', bg='lightskyblue', activebackground='lightskyblue', relief=GROOVE,
                      command=lambda: [modify()])
    sure_btn.place(relx=0.65, rely=0.8, relwidth=0.15, relheight=0.05)


# 查询界面
def inquire():
    inquire_tk = Tk()
    inquire_tk.title('')
    cen.show_center(inquire_tk)
    inquire_tk.resizable(False, False)
    inquire_tk.iconphoto(False, PhotoImage(file="../image/stu.png"))
    inquire_word = Label(inquire_tk, text='查询学生信息', font=('华文新魏', 20))
    inquire_word.place(relx=0.3, rely=0.1, relwidth=0.4, relheight=0.05)

    no = StringVar()

    inquire_label = Label(inquire_tk, text='请输入你要查询的学生学号:', font=('黑体', 13))
    inquire_label.place(relx=0.2, rely=0.3, relwidth=0.6, relheight=0.1)
    no_input = ttk.Entry(inquire_tk, textvariable=no, font=('Microsoft yahei', 10))
    no_input.place(relx=0.3, rely=0.4, relwidth=0.4, relheight=0.05)

    # 查询学生信息
    def inquire_info():
        student_id = no_input.get()
        # print(student_id)
        if os.path.exists(filename):
            r_file = open(filename, 'r', encoding='utf-8')
            student_old = r_file.readlines()
            # print(student_old)
        else:
            return
        for item in student_old:
            d = dict(eval(item))
            # print('----------')
            # print(d)
            # print('----------')
            # print('****')
            # print(student_id)
            # print('****')

            # 判断输入框里的学号和字典里的学号是否匹配
            if d['学号'] == student_id:
                # print('查询到该学生信息!')
                while True:
                    try:
                        no_input.destroy()
                        inquire_label.destroy()
                        inquire_container = Text(inquire_tk, relief=FLAT, font=('华文新魏', 14))
                        inquire_container.place(relx=0.2, rely=0.2, relwidth=0.6, relheight=0.5)

                        def show_student(lst):
                            if len(lst) == 0:
                                showerror(title="错误", message="后台没有学生信息,无数据显示!")
                                # print('没有学生信息,无数据显示!!!')
                            # 内容显示格式
                            content = '{}{}{}{}{}{}'
                            for item in lst:
                                inquire_container.insert(INSERT, content.format('学号: ' + item.get('学号') + '\n\n',
                                                                                '姓名: ' + item.get('姓名') + '\n\n',
                                                                                '性别: ' + item.get('性别') + '\n\n',
                                                                                '年龄: ' + item.get('年龄') + '\n\n',
                                                                                '学院: ' + item.get('学院') + '\n\n',
                                                                                '专业: ' + item.get('专业') + '\n'
                                                                                ))

                        def show_inquire():
                            student_lst = []
                            if os.path.exists(filename):
                                rfile = open(filename, 'r', encoding='utf-8')
                                students = rfile.readlines()
                                if item in students:
                                    student_lst.append(eval(item))
                                show_student(student_lst)

                        show_inquire()
                        # 写入后设置文本框为只读
                        inquire_container.config(state=DISABLED)
                        # 返回按钮
                        back_btn = Button(inquire_tk, text='返回', bg='gainsboro', activebackground='gainsboro',
                                          relief=GROOVE, command=lambda: [inquire_tk.destroy(), inquire()])
                        back_btn.place(relx=0.2, rely=0.8, relwidth=0.15, relheight=0.05)

                        # 确定按钮
                        sure_btn = Button(inquire_tk, text='确定', bg='lightskyblue',
                                          activebackground='lightskyblue', relief=GROOVE,
                                          command=lambda: [inquire_tk.destroy(), main()])
                        sure_btn.place(relx=0.65, rely=0.8, relwidth=0.15, relheight=0.05)
                    except IOError:
                        showerror(title='提示', message='你的输入有误,请重新输入!!!')
                        # print('您的输入有误,请重新输入!!!')
                    else:
                        break
                # print('查询成功!!!')
                break

        # 跳出循环
        else:
            showerror(title='提示', message='查找不到该学生!')
            # print("查找不到该学生!!!")
            # break

    # 返回按钮
    back_btn = Button(inquire_tk, text='返回', bg='gainsboro', activebackground='gainsboro',
                      relief=GROOVE, command=lambda: [inquire_tk.destroy(), main()])
    back_btn.place(relx=0.2, rely=0.8, relwidth=0.15, relheight=0.05)

    # 查询按钮
    revise_btn = Button(inquire_tk, text='查询', bg='lightskyblue', activebackground='lightskyblue',
                        relief=GROOVE, command=lambda: [inquire_info()])
    revise_btn.place(relx=0.65, rely=0.8, relwidth=0.15, relheight=0.05)


# 显示所有学生信息 界面
def show_all():
    all_tk = Tk()
    all_tk.title('')
    cen.show_center(all_tk)
    all_tk.resizable(False, False)
    all_tk.iconphoto(False, PhotoImage(file="../image/stu.png"))
    all_word = Label(all_tk, text='所有学生信息', font=('华文新魏', 20))
    all_word.place(relx=0.3, rely=0.03, relwidth=0.4, relheight=0.05)

    r_file = open(filename, 'r', encoding='utf-8')
    stu_total = r_file.readlines()
    # print(stu_total)

    total_label = Label(all_tk, text='汇总: ')
    total_label.place(relx=0.05, rely=0.05)
    total_text = Text(all_tk, relief=FLAT, bg='#f0f0f0')
    total_text.place(relx=0.11, rely=0.057, relwidth=0.1, relheight=0.03)
    total_text.insert(END, f'{len(stu_total)}')
    total_text.config(state=DISABLED)

    # 滚动文本框
    # scr = scrolledtext.ScrolledText(all_tk, relief=FLAT, wrap=NONE)
    # scr.place(relx=0.05, rely=0.1, relwidth=0.92, relheight=0.7)

    # 表格
    columns = ['学号', '姓名', '性别', '年龄', '学院', '专业']
    table = ttk.Treeview(all_tk, columns=columns, show='headings')  # 隐藏首列
    table.place(relx=0.05, rely=0.1, relwidth=0.9, relheight=0.7)
    y_scroll = Scrollbar(all_tk, orient=VERTICAL)
    y_scroll.configure(command=table.yview)
    y_scroll.place(relx=0.95, rely=0.1, relheight=0.7)

    def show_info(lst):
        if len(lst) == 0:
            showerror(title="错误", message="没有学生信息,无数据显示!")
            # print('没有学生信息,无数据显示!!!')
            return
        # # 表头
        # format_title = '{:^10}\t{:^8}\t{:>8}\t{:>12}\t{:>18}\n'
        # print(format_title.format('学号', '姓名', '年龄', '学院', '专业'))
        # scr.insert(INSERT, format_title.format('学号', '姓名', '年龄', '学院', '专业'))
        # # 内容
        # format_content = '{:^>10}\t{:^8}\t{:>8}\t{:>14}\t{:>14}\n'
        # for item in lst:
        #     scr.insert(INSERT, format_content.format(item.get('学号'),
        #                                              item.get('姓名'),
        #                                              item.get('年龄'),
        #                                              item.get('学院'),
        #                                              item.get('专业')))
        #
        # # 写入后设置文本框为只读
        # scr.config(state=DISABLED)

        # 定义表头
        table.heading('学号', text='学号')
        table.heading('姓名', text='姓名')
        table.heading('性别', text='性别')
        table.heading('年龄', text='年龄')
        table.heading('学院', text='学院')
        table.heading('专业', text='专业')

        # 定义列
        table.column('学号', width=100, minwidth=100, anchor=S)
        table.column('姓名', width=80, minwidth=80, anchor=S)
        table.column('性别', width=40, minwidth=40, anchor=S)
        table.column('年龄', width=40, minwidth=40, anchor=S)
        table.column('学院', width=150, minwidth=150, anchor=S)
        table.column('专业', width=120, minwidth=120, anchor=S)

        for item in lst:
            info = [item.get('学号'),
                    item.get('姓名'),
                    item.get('性别'),
                    item.get('年龄'),
                    item.get('学院'),
                    item.get('专业')]
            table.insert('', END, values=info)

    def show():
        student_lst = []
        # 判断文件是否存在
        if os.path.exists(filename):
            # with open(filename, 'r', encoding='utf-8') as rfile:
            rfile = open(filename, 'r', encoding='utf-8')
            students = rfile.readlines()
            for item in students:
                student_lst.append(eval(item))
            if student_lst:
                show_info(student_lst)
        else:
            showerror(title="错误", message="没有学生信息,无数据显示!")
            # print('暂未保存过数据!!!')

    show()

    back_btn = Button(all_tk, text='返回', bg='gainsboro', activebackground='gainsboro', relief=GROOVE,
                      command=lambda: [all_tk.destroy(), main()])
    back_btn.place(relx=0.2, rely=0.875, relwidth=0.15, relheight=0.05)


# ======================================
# 主界面
def main():
    root = Tk()
    root.title('学生信息管理系统')
    cen.show_center(root)
    root.resizable(False, False)
    # 图标
    root.iconphoto(False, PhotoImage(file="../image/stu.png"))

    # root.iconbitmap("../image/stu.png")

    main_label = Label(root, text='学生信息管理系统', font=('Microsoft yahei', 24), height=5, fg='#484740')
    main_label.place(relx=0.2, rely=-0.1, relwidth=0.6)  # 布局,放置

    add_btn = Button(root, text='添加学生信息', background='lightgreen', activebackground='lightgreen',
                     relief=GROOVE, command=lambda: [root.destroy(), add()])
    add_btn.place(relx=0.3, rely=0.25, relheight=0.1, relwidth=0.4)

    delete_btn = Button(root, text='删除学生信息', background='lightgreen', activebackground='lightgreen',
                        relief=GROOVE, command=lambda: [root.destroy(), delete()])
    delete_btn.place(relx=0.3, rely=0.4, relheight=0.1, relwidth=0.4)

    revise_btn = Button(root, text='修改学生信息', background='lightgreen', activebackground='lightgreen',
                        relief=GROOVE, command=lambda: [root.destroy(), revise()])
    revise_btn.place(relx=0.3, rely=0.55, relheight=0.1, relwidth=0.4)

    # 退出二次确认
    def exit_if():
        exit_result = askquestion(title='退出', message='是否退出?')
        # print('askquestion: %s'.rjust(18) % exit_result)   # 查看返回值
        if exit_result == "yes":
            root.destroy()
        else:
            pass

    exit_btn = Button(root, text='退出', background='gray', activebackground='gray', relief=GROOVE,
                      command=exit_if)
    exit_btn.place(relx=0.3, rely=0.7, relheight=0.1, relwidth=0.4)

    # 绑定事件
    def exit_bind(self):
        exit_if()

    # 绑定ESC键
    root.bind("<Escape>", exit_bind)

    inquire_btn = Button(root, text='查询\n学生\n信息', background='lightblue', activebackground='lightblue',
                         relief=GROOVE, command=lambda: [root.destroy(), inquire()])
    inquire_btn.place(relx=0.1, rely=0.25, relheight=0.5, relwidth=0.1)

    all_btn = Button(root, text='显示\n所有\n学生\n信息', background='lightblue', activebackground='lightblue',
                     relief=GROOVE, command=lambda: [root.destroy(), show_all()])
    all_btn.place(relx=0.8, rely=0.25, relheight=0.5, relwidth=0.1)

    root.mainloop()  # 显示窗口


# 登录界面
def login():
    login_tk = Tk()
    login_tk.title('登录')
    cen.show_center(login_tk)
    login_tk.resizable(False, False)  # 不可调整大小和最大化
    login_tk.iconphoto(False, PhotoImage(file="../image/stu.png"))
    login_word = Label(login_tk, text='登      录', font=('Microsoft yahei', 28), height=5, fg='#5d5553')
    login_word.place(relx=0.3, rely=-0.09, relwidth=0.4)

    # 字样
    no_label = Label(login_tk, text='账号')
    name_label = Label(login_tk, text='密码')
    no_label.place(relx=0.17, rely=0.3, relwidth=0.2, relheight=0.05)
    name_label.place(relx=0.17, rely=0.47, relwidth=0.2, relheight=0.05)

    username = StringVar()
    password = StringVar()

    # 输入框
    username_input = ttk.Entry(login_tk, textvariable=username, font=('Microsoft yahei', 11))
    password_input = ttk.Entry(login_tk, textvariable=password, font=('Microsoft yahei', 11), show='●')  # 隐藏密码
    username_input.place(relx=0.25, rely=0.35, relwidth=0.5, relheight=0.05)
    password_input.place(relx=0.25, rely=0.52, relwidth=0.5, relheight=0.05)

    # 判断
    def user():
        username_txt = username.get()
        password_txt = password.get()
        # print(username_txt)
        # print(password_txt)

        # 账号密码
        if username_txt == '123456' and password_txt == '123456':
            print('登录成功!')
            # 登录成功进入主界面
            login_tk.destroy()
            main()
        elif len(username_txt) == 0:
            # print('请输入账号!')
            showerror(title='提示', message='请输入账号!')
            login_tk.mainloop()
        elif len(password_txt) == 0:
            # print('请输入密码!')
            showerror(title='提示', message='请输入密码!')
            login_tk.mainloop()
        elif username_txt != '123456' and password_txt != '123456':
            # print('登陆失败!')
            showerror(title='提示', message='请输入正确的账号密码!')
            login_tk.mainloop()
        else:
            login_tk.quit()

    login_btn = ttk.Button(login_tk, text='登    录', command=lambda: [user()])
    login_btn.place(relx=0.4, rely=0.72, relwidth=0.2, relheight=0.07)

    # 按钮事件
    def btn_bind(self):
        user()

    # 绑定按钮
    login_tk.bind("<Return>", btn_bind)  # 绑定回车键

    login_tk.mainloop()


if __name__ == '__main__':
    login()

Class.py

import time
from tkinter import Label

filename = '../DB_stu/student.txt'  # 文件名


# 保存文件
class Save_txt:
    @staticmethod
    def save(self):
        try:
            stu_txt = open(filename, 'a', encoding='utf-8')
        except FileNotFoundError:
            stu_txt = open(filename, 'w+', encoding='utf-8')
        for item in self:
            stu_txt.write(str(item) + '\n')  # 将内容写入文件中


# 窗口居中
class Center:
    @staticmethod
    def show_center(self_tk):
        sw = self_tk.winfo_screenwidth()
        sh = self_tk.winfo_screenheight()
        ww = 600
        wh = 500
        x = (sw - ww) / 2
        y = (sh - wh) / 2
        self_tk.geometry("%dx%d+%d+%d" % (ww, wh, x, y))

图标:

 

python学生管理系统报告 学生管理系统python tkinter_python_13

student.txt

{'学号': '202007020028', '姓名': '王光明', '性别': '男', '年龄': 20, '学院': '经济学院', '专业': '电子商务'}
{'学号': '202100620002', '姓名': '李白', '性别': '男', '年龄': 19, '学院': '现代信息产业学院', '专业': '人工智能'}
{'学号': '202003220015', '姓名': '赵六娇', '性别': '女', '年龄': 21, '学院': '会计学院', '专业': '会计学'}
{'学号': '202205220033', '姓名': '李新春', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '商务英语'}
{'学号': '202106120041', '姓名': '李建国', '性别': '男', '年龄': 20, '学院': '信息技术与工程学院', '专业': '物联网'}
{'学号': '202202010040', '姓名': '张光明', '性别': '男', '年龄': 19, '学院': '法学院', '专业': '法学'}
{'学号': '202007020025', '姓名': '王国保', '性别': '男', '年龄': 20, '学院': '经济学院', '专业': '经济学'}
{'学号': '202100620008', '姓名': '钟馗', '性别': '男', '年龄': 19, '学院': '现代信息产业学院', '专业': '智能讯飞'}
{'学号': '202003220019', '姓名': '欧阳帅', '性别': '男', '年龄': 21, '学院': '管理学院', '专业': '物流管理'}
{'学号': '202205220023', '姓名': '钟葵', '性别': '女', '年龄': 18, '学院': '外国语学院', '专业': '西班牙语'}
{'学号': '202107720055', '姓名': '程梨花', '性别': '女', '年龄': 20, '学院': '信息技术与工程学院', '专业': '软件工程'}
{'学号': '202207550065', '姓名': '黄国行', '性别': '男', '年龄': 19, '学院': '法学院', '专业': '法学'}
{'学号': '202000990044', '姓名': '欧扬风', '性别': '男', '年龄': 20, '学院': '经济学院', '专业': '经济学'}
{'学号': '202134650013', '姓名': '何家', '性别': '女', '年龄': 19, '学院': '艺术设计学院', '专业': '视觉传达'}
{'学号': '202000870036', '姓名': '赵福', '性别': '男', '年龄': 21, '学院': '会计学院', '专业': '会计学'}
{'学号': '202207880015', '姓名': '白柏林', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '日语'}
{'学号': '202107720016', '姓名': '蔡家豪', '性别': '男', '年龄': 20, '学院': '信息技术与工程学院', '专业': '物联网'}
{'学号': '202207110027', '姓名': '严离离', '性别': '女', '年龄': 19, '学院': '法学院', '专业': '法学'}
{'学号': '202002080040', '姓名': '沈锅锅', '性别': '女', '年龄': 20, '学院': '经济学院', '专业': '经济学'}
{'学号': '202105110016', '姓名': '王安时', '性别': '男', '年龄': 19, '学院': '现代信息产业学院', '专业': '智能讯飞'}
{'学号': '202029420038', '姓名': '欧阳帅', '性别': '男', '年龄': 21, '学院': '管理学院', '专业': '酒店管理'}
{'学号': '202233300016', '姓名': '苏政', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '德语'}
{'学号': '202209060028', '姓名': '吴茉莉', '性别': '女', '年龄': 19, '学院': '现代信息产业学院', '专业': '大数据'}
{'学号': '202000780015', '姓名': '常北北', '性别': '女', '年龄': 20, '学院': '经济学院', '专业': '金融学'}
{'学号': '202100640029', '姓名': '冯书节', '性别': '男', '年龄': 19, '学院': '现代信息产业学院', '专业': '计科华为'}
{'学号': '202000780027', '姓名': '欧明姚', '性别': '男', '年龄': 21, '学院': '会计学院', '专业': '审计学'}
{'学号': '202202280018', '姓名': '罗浩', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '德语'}
{'学号': '202200550017', '姓名': '曹永达', '性别': '男', '年龄': 18, '学院': '国际学院', '专业': '市营双语创新'}
{'学号': '202244400016', '姓名': '段岚', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '日语'}
{'学号': '202209010028', '姓名': '李璐', '性别': '女', '年龄': 19, '学院': '现代信息产业学院', '专业': '大数据'}
{'学号': '202000390015', '姓名': '武子韬', '性别': '男', '年龄': 20, '学院': '经济学院', '专业': '金融学'}
{'学号': '202100880029', '姓名': '龚杰宏', '性别': '男', '年龄': 19, '学院': '现代信息产业学院', '专业': '计科华为'}
{'学号': '202054670027', '姓名': '钟云熙', '性别': '女', '年龄': 21, '学院': '会计学院', '专业': '审计学'}
{'学号': '202245890018', '姓名': '蔡致远', '性别': '男', '年龄': 18, '学院': '外国语学院', '专业': '德语'}
{'学号': '202200660017', '姓名': '郑岚', '性别': '女', '年龄': 18, '学院': '国际学院', '专业': '市营双语创新'}
{'学号': '202202010013', '姓名': '小明', '性别': '男', '年龄': 20, '学院': '信息技术与工程学院', '专业': '软件工程'}