基于 Python ttkbootstrap 库的简单学生管理系统实现。

前言

   以前学习python的过程中,接触过python的tkinter库,一个标准简单且传统的GUI库,他提供了基本的图形界面组件,虽然能满足大部分需求,但是外观嘛……就有点不尽人意了,很多同学应该深有感受。

   基于时代局限性,tkinter库已经过有些时了,所有我就在想有没有什么好的python GUI库能够使用,经过搜索调查,界面精美的GUI库有很多,比如wxpython库,kivy库,以及最出名的pyqt库,这些库的功能很强大,优点很多,但是缺点就是学习曲线过于陡峭,对于新手来说很难掌握(对于我这个初学者更是),不如自带的tkinter库简单易学,但是tkinter库外形一言难尽,不符合正常的审美,所以有一个问题,就是有没有一种基于tkinter的简单易学和界面不错的库呢?

    那当然是有的,python丰富的库海可不是随便说说的,这个替代的库就是我们今天所说的主角,ttkbootstrap库。

    介绍完ttkbootstrap库后,我会将自己用ttkbootstrap库写的学生管理系统的代码附上,供大家玩一下。


一、ttkbootstrap库是什么?

1.简单介绍

  ttkbootstrap 是一个基于 Tkinter 扩展的Python GUI 库,旨在为 Tkinter 应用提供现代化的主题和美化控件。它扩展了 Tkinter 中的标准控件,提供了更丰富的样式和主题,帮助开发者创建更具现代感的桌面应用。

    它的目标是为 Tkinter 提供一种更简洁且美观的方式,让用户界面不再显得过时和笨重,给 Tkinter 的控件赋予更符合现代设计趋势的外观,比如 Material Design 风格、扁平化设计等。

    用人话来说,ttkbootstrap库就是tkinte库化妆后的样子,比之前要精致的多。

    在用法和设计方面,ttkbootstrap能完成继承tkinter,也就是说,你只要会tkinter,那么只需要稍微熟悉一下ttkbootstrap库就能使用,对于刚开始接触python GUI库的学习者来说,非常的友善。精致的页面,丰富组件,以及跨平台和社区开源,ttkbootstrap完全可以开发一些小型项目,样式也符合现代化,下面我们会简单介绍一下。

2.下载

使用ttkbootstrap库需要下载,如果配置好python各种环境变量,可以打开cmd命令窗口,输入以下命令下载:

pip install ttkbootstrap

或者使用清华大学镜像源,下载速度会更快

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ttkbootstrap

二、主要功能展示

1.主窗口对比

这是tkinter的窗口样式

代码:


import tkinter as tk

# 创建主窗口
root = tk.Tk()
root.title("简单的 Tkinter 窗口")
root.geometry("300x200")  # 设置窗口大小

# 创建一个标签
label = tk.Label(root, text="你好,欢迎使用 Tkinter!")
label.pack(pady=20)  # 使用 pack 布局并设置垂直间距

# 启动应用
root.mainloop()

ttkbootstrap的主窗口

代码:

import ttkbootstrap as ttk

# ttkbootstrap的主窗口是Window
root = ttk.Window()
root.title("ttkbootstrap窗口")
root.geometry("300x200")  # 设置窗口大小

# 创建一个标签
label = ttk.Label(root, text="你好,欢迎使用ttkbootstrap!")
label.pack(pady=20)  # 使用 pack 布局并设置垂直间距
# 启动应用
root.mainloop()

对比的效果很明显,而且ttkbootstrap库内部设置了很多的主题,深色主题有solar,superhero,darkly,cyborg,vapor,浅色主题有cosmo,flatly,journal,litera,lumen,morph等,下面展示几个:

     

主题的更改很简单,只要将主题类型传入窗口类中的themename参数就行了。

import ttkbootstrap as ttk
# 主题类型solar,superhero,darkly,cyborg,vapor,cosmo,flatly,journal,litera,lumen,morph等
# 窗口Window 中的themename替换相应的主题即可
# 例如:
root = ttk.Window(themename="journal")
root.title("ttkbootstrap 主题展示")
root.geometry("300x200")
#标签
ttk.Label(text="这是journal主题").pack()
# 创建一个简单的按钮
button = ttk.Button(root, text="点击我", bootstyle="PRIMARY")
button.pack(pady=20)

# 启动主循环
root.mainloop()

2.常用组件对比

展示几个常用的组件,后面的学生管理系统就是用这些组件做得。

1.标签

          

对比很明显,tkinter:简单且基础,通常用于基本的文本显示,较为传统。

ttkbootstrap:可支持多种主题,标签的外观更现代,也根精致

ttkbootstrap标签代码:

import ttkbootstrap as ttk

# 创建主窗口
root = ttk.Window()
root.title("ttkbootstrap标签")

# 创建一个标签,使用现代化的字体和样式
label = ttk.Label(root, text="Hello, ttkbootstrap!", font=("Arial", 16))
label.pack(pady=20)  
# 启动主循环
root.mainloop()

2.按钮

代码:

import tkinter as tk

root = tk.Tk()
button = tk.Button(root, text="点击我")
button.pack(pady=20)
root.geometry("300x200")
root.mainloop()

和窗口样式一样,ttkbootstrap内置了不同按钮样式,有Primary,Success,Info,Warning,Danger,Light,Dark,Link等按钮样式。

代码如下,可以自己运行一下:

import ttkbootstrap as ttk
from ttkbootstrap.constants import *

# 创建主窗口
root = ttk.Window(themename="superhero")
root.title("ttkbootstrap 按钮样式展示")

# 创建按钮并显示
button1 = ttk.Button(root, text="Primary Button", bootstyle=PRIMARY)
button1.pack(pady=10, padx=20, fill="x")

button2 = ttk.Button(root, text="Success Button", bootstyle=SUCCESS)
button2.pack(pady=10, padx=20, fill="x")

button3 = ttk.Button(root, text="Info Button", bootstyle=INFO)
button3.pack(pady=10, padx=20, fill="x")

button4 = ttk.Button(root, text="Warning Button", bootstyle=WARNING)
button4.pack(pady=10, padx=20, fill="x")

button5 = ttk.Button(root, text="Danger Button", bootstyle=DANGER)
button5.pack(pady=10, padx=20, fill="x")

button6 = ttk.Button(root, text="Light Button", bootstyle=LIGHT)
button6.pack(pady=10, padx=20, fill="x")

button7 = ttk.Button(root, text="Dark Button", bootstyle=DARK)
button7.pack(pady=10, padx=20, fill="x")

button8 = ttk.Button(root, text="Link Button", bootstyle=LINK)
button8.pack(pady=10, padx=20, fill="x")

# 启动主循环
root.mainloop()

注:改变按钮样式和窗口主题差不多,只需要将按钮类中bootstyle参数设置一下。

2.输入框

tkinter输入框

ttkbootstrap输入框

代码:

import ttkbootstrap as ttk
#主窗口
root = ttk.Window()
#窗口大小
root.geometry("300x200")
#输入框
entry = ttk.Entry(root)
entry.pack(pady=20)
#窗口启动
root.mainloop()

3.复选框

   

ttkbootstrap复选框代码:

import tkinter as tk
import ttkbootstrap as ttk

# 创建主窗口
root = ttk.Window()
root.title("ttkbootstrap 复选框")

# 创建复选框
var = tk.IntVar()
checkbutton = ttk.Checkbutton(root, text="复选框", variable=var)
checkbutton.pack(pady=20)  # 添加到窗口并设置垂直间距
root.geometry("300x200")
# 启动主循环
root.mainloop()

4.下拉框

ttkbootstrap下拉框

      

ttkbootstrap下拉框代码:


import ttkbootstrap as ttk

# 创建主窗口
root = ttk.Window()
root.title("ttkbootstrap 下拉框示例")

# 创建一个 ttkbootstrap 的 下拉框
options = ["苹果", "香蕉", "橙子", "葡萄", "梨"]
selected_option = ttk.StringVar()  # 用于存储选中的值

combobox = ttk.Combobox(root, textvariable=selected_option, values=options, state="readonly", width=20)
combobox.set("苹果")  # 设置默认选择项
combobox.pack(pady=20)

# 显示选择的选项
def show_selection():
    label.config(text="您选择的是: " + selected_option.get())

# 创建按钮
button = ttk.Button(root, text="显示选择", command=show_selection)
button.pack(pady=10)

# 标签,用于显示选择结果
label = ttk.Label(root, text="您选择的是: " + selected_option.get())
label.pack()
root.geometry("300x200")
# 启动主循环
root.mainloop()

5.Treeview

 Treeview 是 Tkinter 中非常强大的控件,它可以用来以树形结构展示具有层级关系的数据。它支持多列显示、节点的增删改查、节点的展开与折叠等功能,常用于文件管理器、组织结构图、分类展示等应用场景。结合现代化主题(如 ttkbootstrap 提供的样式),Treeview 可以大大增强用户界面的可用性和美观性。

    学生管理系统中的学生展示就是用Treeview组件做得。

  

ttkbootstrap Treeview代码如下

import ttkbootstrap as ttk

# 创建主窗口
root = ttk.Window()
root.title("ttkbootstrap Treeview 示例")



# 创建 Treeview 控件
tree = ttk.Treeview(root, columns=("Name", "Age"), show="headings", style="success.Treeview")

# 定义列
tree.heading("Name", text="Name")
tree.heading("Age", text="Age")

# 插入数据
tree.insert("", "end", values=("Alice", 30))
tree.insert("", "end", values=("Bob", 25))
tree.insert("", "end", values=("Charlie", 35))

# 布局 Treeview
tree.pack(pady=20)

# 启动主循环
root.mainloop()

三、学生管理系统

搭建环境:

python 版本 3.7以上最好

ttkbootstrap版本 1.10.1

1.学生管理系统

这个管理系统比较简单,不与数据库进行交互,可以实现基本的功能,如添加学生,修改学生信息,删除学生,按成绩排序,显示所有学生,保存信息,退出系统等。

2.学生类

学生信息,包括学号,姓名,所属学部,课程,成绩等,字典虽然可以存储学生信息,但是不如对象简洁明了和易扩展

学生类代码:

# 学生类,用来存储学生信息
class Student:
    def __init__(self, student_id, name, department, course, grade):
        #学号
        self.student_id = student_id
        #姓名
        self.name = name
        #所属学部
        self.department = department
        #课程
        self.course = course
        #成绩
        self.grade = grade
    
    #用来打印学生信息
    def __str__(self):
        return f"{self.student_id} | {self.name} | {self.department} | {self.course} | {self.grade}"

3.登录模块

代码如下:

class Login:
    def __init__(self, parent):
        self.parent = parent
        #默认账户
        self.username = "admin"
        #默认密码
        self.password = "password"
        # 获取屏幕的宽度和高度
        screen_width = self.parent.winfo_screenwidth()
        screen_height = self.parent.winfo_screenheight()
        # 设置窗口的尺寸
        window_width = 650
        window_height = 400
        # 计算窗口放置的位置(使其居中)
        position_top = (screen_height // 2) - (window_height // 2)
        position_left = (screen_width // 2) - (window_width // 2)
        # 设置窗口大小和位置
        self.parent.geometry(f"{window_width}x{window_height}+{position_left}+{position_top}")
        self.parent.title("学生信息管理系统登录")
        self.parent.config(bg="#f0f0f0")

        # 使用Frame来构建登录界面
        self.frame = ttk.Frame(self.parent, padding="30 20 30 20")
        self.frame.place(relx=0.5, rely=0.5, anchor="center")
        
        # 设置用户名标签
        ttk.Label(self.frame, text="用户名:", font=("微软雅黑", 12), background="#f0f0f0").grid(row=0, column=0, padx=10, pady=10, sticky="w")
        self.username_entry = ttk.Entry(self.frame, font=("微软雅黑", 12), width=20, justify="center")
        self.username_entry.grid(row=0, column=1, padx=10, pady=10)
        
        # 设置密码标签
        ttk.Label(self.frame, text="密码:", font=("微软雅黑", 12), background="#f0f0f0").grid(row=1, column=0, padx=10, pady=10, sticky="w")
        self.password_entry = ttk.Entry(self.frame, font=("微软雅黑", 12), show="*", width=20, justify="center")
        self.password_entry.grid(row=1, column=1, padx=10, pady=10)
        # 免密码登录
        self.login_button = ttk.Button(self.frame, text="免密登录", command=self.no_password, width=20, padding="5", 
                                       style="TButton")
        self.login_button.grid(row=2, column=0, columnspan=1, pady=20)
        
        # 登录按钮样式
        self.login_button = ttk.Button(self.frame, text="登录", command=self.login, width=20, padding="5", 
                                       style="TButton")
        self.login_button.grid(row=2, column=1, columnspan=1, pady=20)

        # 设置按钮的样式
        style = ttk.Style()
        style.configure("TButton", font=("微软雅黑", 12), padding=10, relief="flat", background="#4CAF50", foreground="white")
       

    def login(self):
        username = self.username_entry.get()
        password = self.password_entry.get()

        if username == self.username and password == self.password:
            Messagebox.show_info("登录成功", "欢迎来到学生信息管理系统!")
            self.frame.destroy()
         
            StudentManagerApp(self.parent)
        else:
            Messagebox.show_error("登录失败", "用户名或密码错误,请重新尝试!")

    def no_password(self):
        self.frame.destroy()
        StudentManagerApp(self.parent)

登录框设计很简单,效果演示如下:

默认的账号密码是(admin,password),不想输入账号密码可以点击免密登录,不然每次都输入一遍实在是麻烦。

4.系统主窗口

代码如下:

# 学生信息管理系统主界面
class StudentManagerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("学生信息管理系统")
        self.root.geometry("600x700")
        
        self.style = ttk.Style(theme="superhero")  # 使用ttkbootstrap样式
        self.manager = StudentManager()
        self.frame = ttk.Frame(self.root, padding="30 20 30 20", relief="solid", borderwidth=1)
        self.frame.place(relx=0.5, rely=0.5, anchor="center", width=500, height=400)

        # 在frame中放置标签
        ttk.Label(self.frame, text="学生信息管理系统", font=("Helvetica", 24)).grid(row=0, column=0, columnspan=2, pady=20)

        # 配置frame的行列,使得每个单元格能够扩展并居中
        self.frame.grid_rowconfigure(0, weight=1)
        self.frame.grid_rowconfigure(1, weight=1)
        self.frame.grid_rowconfigure(2, weight=1)
        self.frame.grid_rowconfigure(3, weight=1)
        self.frame.grid_rowconfigure(4, weight=1)

        self.frame.grid_columnconfigure(0, weight=1)
        self.frame.grid_columnconfigure(1, weight=1)

        # 第一行按钮(添加学生,修改学生)
        self.add_button = ttk.Button(self.frame, text="添加学生", command=self.open_add_student_window, width=20, padding=10)
        self.add_button.grid(row=1, column=0, padx=10, pady=10, sticky="nsew")

        self.update_button = ttk.Button(self.frame, text="修改学生", command=self.open_update_student_window, width=20, padding=10)
        self.update_button.grid(row=1, column=1, padx=10, pady=10, sticky="nsew")

        # 第二行按钮(删除学生,按成绩排序)
        self.delete_button = ttk.Button(self.frame, text="删除学生", command=self.open_delete_student_window, width=20, padding=10)
        self.delete_button.grid(row=2, column=0, padx=10, pady=10, sticky="nsew")

        self.sort_button = ttk.Button(self.frame, text="按成绩排序", command=self.open_sort_students_window, width=20, padding=10)
        self.sort_button.grid(row=2, column=1, padx=10, pady=10, sticky="nsew")

        # 第三行按钮(显示所有学生,保存信息)
        self.show_button = ttk.Button(self.frame, text="显示所有学生", command=self.open_show_all_students_window, width=20, padding=10)
        self.show_button.grid(row=3, column=0, padx=10, pady=10, sticky="nsew")

        self.save_button = ttk.Button(self.frame, text="保存信息", command=self.save_info, width=20, padding=10)
        self.save_button.grid(row=3, column=1, padx=10, pady=10, sticky="nsew")

        # 第四行按钮(退出系统)
        self.exit_button = ttk.Button(self.frame, text="退出系统", command=self.root.quit, width=20, padding=10)
        self.exit_button.grid(row=4, column=0, columnspan=2, padx=10, pady=10, sticky="nsew")
        #添加学生
    def open_add_student_window(self):
        AddStudentWindow(self.root, self.manager)
        #修改学生
    def open_update_student_window(self):
        UpdateStudentWindow(self.root, self.manager)
        #删除学生
    def open_delete_student_window(self):
        DeleteStudentWindow(self.root, self.manager)
        #成绩排序
    def open_sort_students_window(self):
        SortStudentsWindow(self.root, self.manager)
        #显示所有学生
    def open_show_all_students_window(self):
        ShowAllStudentsWindow(self.root, self.manager)
        #保存信息
    def save_info(self):
        self.manager.save_to_file()
        Messagebox.show_info("保存成功", "学生信息已成功保存到文件。")

效果如下:

5.显示所有的学生

在启动管理系统时,会默认在当前目录下生成students.dat文件,里面默认插入了十条学生数据。

代码模块如下:

#显示所有学生信息
class ShowAllStudentsWindow:
    def __init__(self, parent, manager):
        self.parent = parent
        self.manager = manager
        # 创建一个新窗口
        self.window = ttk.Toplevel(parent)
        self.window.title("显示所有学生信息")
        # 设置窗口位置和大小
        Position(self.parent, self.window, (610, 450), hposition=300)

        # 创建Treeview控件
        self.treeview = ttk.Treeview(self.window, columns=("学号", "姓名", "学部", "课程", "成绩"), show="headings")
        
        # 设置列标题
        self.treeview.heading("学号", text="学号")
        self.treeview.heading("姓名", text="姓名")
        self.treeview.heading("学部", text="学部")
        self.treeview.heading("课程", text="课程")
        self.treeview.heading("成绩", text="成绩")
        
        # 设置列宽度
        self.treeview.column("学号", width=100, anchor="center")
        self.treeview.column("姓名", width=100, anchor="center")
        self.treeview.column("学部", width=150, anchor="center")
        self.treeview.column("课程", width=150, anchor="center")
        self.treeview.column("成绩", width=100, anchor="center")
        
        # 滚动条
        scrollbar = ttk.Scrollbar(self.window, orient="vertical", command=self.treeview.yview)
        self.treeview.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")

        # 将Treeview放置到窗口中
        self.treeview.pack(fill=ttk.BOTH, padx=10, pady=10)

        # 显示所有学生信息
        self.show_all_students()

    def show_all_students(self):
        # 清除现有数据
        for item in self.treeview.get_children():
            self.treeview.delete(item)
         # 添加学生信息
        for student in self.manager.show_all_students():
            self.treeview.insert("", "end", values=(student.student_id, student.name, student.department, student.course, student.grade))

效果如下:

5.添加学生

代码如下:

# 添加学生界面
class AddStudentWindow:
    def __init__(self, parent, manager):
        self.parent = parent
        self.manager = manager
        self.window = ttk.Toplevel(self.parent)
        self.window.title("添加学生")
        Position(self.parent,self.window,size=(500,450))
        self.frame = ttk.Frame(self.window, padding="30 20 30 20")
        self.frame.place(relx=0.5, rely=0.5, anchor="center",width=400,height=400)
        # 学生信息输入框
        ttk.Label(self.frame, text="学号:").grid(row=0, column=0, padx=10, pady=10)
        self.student_id_entry = ttk.Entry(self.frame)
        self.student_id_entry.grid(row=0, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="姓名:").grid(row=1, column=0, padx=10, pady=10)
        self.student_name_entry = ttk.Entry(self.frame)
        self.student_name_entry.grid(row=1, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="所在系:").grid(row=2, column=0, padx=10, pady=10)
        self.department_entry = ttk.Entry(self.frame)
        self.department_entry.grid(row=2, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="课程:").grid(row=3, column=0, padx=10, pady=10)
        self.course_entry = ttk.Entry(self.frame)
        self.course_entry.grid(row=3, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="成绩:").grid(row=4, column=0, padx=10, pady=10)
        self.grade_entry = ttk.Entry(self.frame)
        self.grade_entry.grid(row=4, column=1, padx=10, pady=10)

        self.add_button = ttk.Button(self.frame, text="添加", command=self.add_student,width=10)
        self.add_button.grid(row=5, column=0, columnspan=2, pady=10)

    def add_student(self):
        student_id = self.student_id_entry.get()
        name = self.student_name_entry.get()
        department = self.department_entry.get()
        course = self.course_entry.get()
        grade = self.grade_entry.get()

        # 验证数据
        if not self.validate_student_id(student_id):
            Messagebox.show_error(title="错误", message="学号格式不正确,请重新输入。",parent=self.window)
            return
        if not self.validate_name(name):
            Messagebox.show_error(title="错误", message="姓名不能包含字母或为空,请重新输入。",parent=self.window)
            return
        if not self.validate_department(department):
            Messagebox.show_error(title="错误", message="系别不能为空,请重新输入。",parent=self.window)
            return
        if not self.validate_course(course):
            Messagebox.show_error(title="错误", message="课程不能为空,请重新输入。",parent=self.window)
            return
        if not self.validate_grade(grade):
            Messagebox.show_error(title="错误", message="成绩无效,请输入有效的成绩(0-100)。",parent=self.window)
            return
        
        # 创建学生对象并添加
        student = Student(student_id, name, department, course, float(grade))
        self.manager.add_student(student)

        # 提示信息
        Messagebox.show_info(parent=self.window, title="添加成功", message="学生已添加")
        self.window.destroy()

    # 数据验证方法

    def validate_student_id(self, student_id):
        # 验证学号是否为数字且长度符合要求
        return student_id.isdigit()   
    
    def validate_name(self, name):
        # 验证姓名不能包含字母,只能包含数字、空格或其他特殊字符
        return bool(re.match("^[^a-zA-Z]*$", name)) and bool(name.strip())

    def validate_department(self, department):
        # 验证部门是否为空
        return bool(department.strip())

    def validate_course(self, course):
        # 验证课程是否为空
        return bool(course.strip())

    def validate_grade(self, grade):
        # 验证成绩是否为数字且在0到100之间
        try:
            grade = float(grade)
            return 0 <= grade <= 100
        except ValueError:
            return False

效果如下:

 ​​​​​​​

添加学生模块设计了简单验证规则,防止用户输入的学生信息不合理,将待添加学生的数据输入后点击添加就可以了。

6.修改学生

代码:

# 修改学生信息界面
class UpdateStudentWindow:
    def __init__(self, parent, manager):
        self.parent = parent
        self.manager = manager
        self.window = ttk.Toplevel(parent)
        self.window.title("修改学生信息")
        Position(self.parent,self.window,hposition=200,size=(400,450))
        self.frame = ttk.Frame(self.window, padding="30 20 30 20")
        self.frame.place(relx=0.5, rely=0.5, anchor="center",width=400,height=400)

        ttk.Label(self.frame, text="学号:").grid(row=0, column=0, padx=10, pady=10)
        self.student_id_entry = ttk.Entry(self.frame)
        self.student_id_entry.grid(row=0, column=1, padx=10, pady=10)

        self.find_button = ttk.Button(self.frame, text="查找", command=self.find_student,width=10)
        self.find_button.grid(row=1, column=0, columnspan=2, pady=10)

        ttk.Label(self.frame, text="姓名:").grid(row=2, column=0, padx=10, pady=10)
        self.student_name_entry = ttk.Entry(self.frame)
        self.student_name_entry.grid(row=2, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="所在系:").grid(row=3, column=0, padx=10, pady=10)
        self.department_entry = ttk.Entry(self.frame)
        self.department_entry.grid(row=3, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="课程:").grid(row=4, column=0, padx=10, pady=10)
        self.course_entry = ttk.Entry(self.frame)
        self.course_entry.grid(row=4, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="成绩:").grid(row=5, column=0, padx=10, pady=10)
        self.grade_entry = ttk.Entry(self.frame)
        self.grade_entry.grid(row=5, column=1, padx=10, pady=10)

        self.update_button = ttk.Button(self.frame, text="更新", command=self.update_student,width=10)
        self.update_button.grid(row=6, column=0, columnspan=2, pady=10)

    def find_student(self):
        student_id = self.student_id_entry.get()
        student = self.manager.find_student(student_id)

        if student:
            self.student_name_entry.delete(0, ttk.END)
            self.student_name_entry.insert(0, student.name)

            self.department_entry.delete(0, ttk.END)
            self.department_entry.insert(0, student.department)

            self.course_entry.delete(0, ttk.END)
            self.course_entry.insert(0, student.course)

            self.grade_entry.delete(0, ttk.END)
            self.grade_entry.insert(0, student.grade)
        else:
            Messagebox.show_error(parent=self.window,message="没有找到学生信息")

    def update_student(self):
        student_id = self.student_id_entry.get()
        name = self.student_name_entry.get()
        department = self.department_entry.get()
        course = self.course_entry.get()
        grade = float(self.grade_entry.get())

        self.manager.update_student(student_id, name, department, course, grade)
        Messagebox.show_info("修改信息成功!","修改学生信息",self.window)
        self.window.destroy()

修改学生的同时也能查找学生,比如查找学号为1001的学生,效果展示如下:

     ​​​​​​​

当查找出学生的时候,就可以修改对应的数据了。

7.删除学生

删除模块代码如下:

# 删除学生信息界面
class DeleteStudentWindow:
    def __init__(self, parent, manager):
        self.parent = parent
        self.manager = manager
        #显示删除窗口
        self.window = ttk.Toplevel(parent)
        self.window.title("删除学生")
        #调整窗口位置和默认大小
        Position(self.parent,self.window,hposition=200,size=(400,150))
        self.frame = ttk.Frame(self.window, padding="30 20 30 20")
        self.frame.place(relx=0.5, rely=0.5, anchor="center",width=400,height=150)
        ttk.Label(self.frame, text="学号:").grid(row=0, column=0, padx=10, pady=10)
        self.student_id_entry = ttk.Entry(self.frame)
        self.student_id_entry.grid(row=0, column=1, padx=10, pady=10)

        self.delete_button = ttk.Button(self.frame, text="删除", command=self.delete_student)
        self.delete_button.grid(row=1, column=0, columnspan=2, pady=10)

    def delete_student(self):
        student_id = self.student_id_entry.get()
        #将要删除学生的学号传入管理类。
        self.manager.delete_student(student_id)
        Messagebox.show_info("删除成功", "学生信息已删除!")
        #删除当前的窗口
        self.window.destroy()

效果演示:

输入对应的学号就可以删除了对应学生信息了。

8.成绩排序

代码如下:

# 按成绩排序显示学生信息界面
class SortStudentsWindow:
    def __init__(self, parent, manager):
        self.parent = parent
        self.manager = manager
        self.window = ttk.Toplevel(parent)
        self.window.title("按成绩排序")
        Position(self.parent, self.window, (610, 450), hposition=300)
   
         # 创建Treeview控件
        self.treeview = ttk.Treeview(self.window, columns=("学号", "姓名", "学部", "课程", "成绩"), show="headings")
        
        # 设置列标题
        self.treeview.heading("学号", text="学号")
        self.treeview.heading("姓名", text="姓名")
        self.treeview.heading("学部", text="学部")
        self.treeview.heading("课程", text="课程")
        self.treeview.heading("成绩", text="成绩")
        
        # 设置列宽度
        self.treeview.column("学号", width=100, anchor="center")
        self.treeview.column("姓名", width=100, anchor="center")
        self.treeview.column("学部", width=150, anchor="center")
        self.treeview.column("课程", width=150, anchor="center")
        self.treeview.column("成绩", width=100, anchor="center")
        
        # 滚动条
        scrollbar = ttk.Scrollbar(self.window, orient="vertical", command=self.treeview.yview)
        self.treeview.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")

        # 将Treeview放置到窗口中
        self.treeview.pack(fill=ttk.BOTH, padx=10, pady=10)


        self.show_sorted_students()

    def show_sorted_students(self):

        sorted_students = self.manager.sort_by_grade()
        for student in sorted_students:
            self.treeview.insert("", "end", values=(student.student_id, student.name, student.department, student.course, student.grade))

效果如下:

9.保存/退出

1.点击保存按钮就会将添加或更改的数据保存到当前目录下的students.dat目录下(初始化时会自动的生成),后面再次启动时会自动的加载,保证数据不会丢失。

2.点击退出就关闭系统。

保存文件,以及加载文件的功能类如下:

class StudentManager:
    def __init__(self):
        self.students = []
        self.load_from_file()

        # 如果文件不存在或文件为空,则插入默认数据
        if not self.students:
            self.load_default_data()
            self.save_to_file()
      
    # 默认插入十条学生数据
    def load_default_data(self):
        self.students = [
            Student("1001", "张三", "计算机与人工智能学部", "Python程序设计", 85.5),
            Student("1002", "李四", "计算机与人工智能学部", "数据结构", 90.0),
            Student("1003", "王五", "电子与信息学部", "电路基础", 78.5),
            Student("1004", "赵六", "计算机与人工智能学部", "数据库原理", 88.0),
            Student("1005", "孙七", "信息科学与技术学部", "计算机网络", 92.5),
            Student("1006", "周八", "计算机与人工智能学部", "操作系统", 80.0),
            Student("1007", "吴九", "计算机与人工智能学部", "编译原理", 86.5),
            Student("1008", "郑十", "信息科学与技术学部", "数据挖掘", 75.5),
            Student("1009", "钱十一", "电子与信息学部", "人工智能基础", 83.0),
            Student("1010", "陈十二", "计算机与人工智能学部", "Python程序设计", 89.0),
        ]
    
    #添加学生操作
    def add_student(self, student):
        self.students.append(student)
        self.save_to_file()
    #寻找学生
    def find_student(self, student_id):
        for student in self.students:
            if student.student_id == student_id:
                return student
        return None
    #删除学生
    def delete_student(self, student_id):
        self.students = [student for student in self.students if student.student_id != student_id]
        self.save_to_file()
    #更新学生
    def update_student(self, student_id, name, department, course, grade):
        student = self.find_student(student_id)
        if student:
            student.name = name
            student.department = department
            student.course = course
            student.grade = grade
            self.save_to_file()
    #学生成绩排序
    def sort_by_grade(self):
        return sorted(self.students, key=lambda x: x.grade, reverse=True)
    #显示所以学生
    def show_all_students(self):
        return self.students
    #保存文件
    def save_to_file(self):
        with open('students.dat', 'wb') as file:
            pickle.dump(self.students, file)
    #加载文件
    def load_from_file(self):
        if os.path.exists('students.dat'):
            try:
                with open('students.dat', 'rb') as file:
                    self.students = pickle.load(file)
            except (EOFError, pickle.UnpicklingError):
                # 如果文件为空或损坏,则初始化为空列表
                self.students = []
        else:
            self.students = []

四、整体代码

import ttkbootstrap as ttk
from ttkbootstrap.dialogs import Messagebox
import pickle
from typing import Tuple
import re
import os

# 学生类,用来存储学生信息
class Student:
    def __init__(self, student_id, name, department, course, grade):
        #学号
        self.student_id = student_id
        #姓名
        self.name = name
        #所属学部
        self.department = department
        #课程
        self.course = course
        #成绩
        self.grade = grade
    
    #用来打印学生信息
    def __str__(self):
        return f"{self.student_id} | {self.name} | {self.department} | {self.course} | {self.grade}"

# 调整弹出窗口的位置
class Position:

    def __init__(self,window,widget,size:Tuple[int,int]=(300,450),hposition:int=0,vposition:int=0):
        self.window=window
        self.size=size
        self.widget=widget
        self.hposition=hposition
        self.vposition=vposition
        self.adjust_position()

    def adjust_position(self):

        self.parent_x = self.window.winfo_rootx()-self.hposition
        self.parent_y = self.window.winfo_rooty()-self.vposition
        
        self.widget.geometry(f"{self.size[0]}x{self.size[1]}+{self.parent_x}+{self.parent_y}")
        
class StudentManager:
    def __init__(self):
        self.students = []
        self.load_from_file()

        # 如果文件不存在或文件为空,则插入默认数据
        if not self.students:
            self.load_default_data()
            self.save_to_file()
      
    # 默认插入十条学生数据
    def load_default_data(self):
        self.students = [
            Student("1001", "张三", "计算机与人工智能学部", "Python程序设计", 85.5),
            Student("1002", "李四", "计算机与人工智能学部", "数据结构", 90.0),
            Student("1003", "王五", "电子与信息学部", "电路基础", 78.5),
            Student("1004", "赵六", "计算机与人工智能学部", "数据库原理", 88.0),
            Student("1005", "孙七", "信息科学与技术学部", "计算机网络", 92.5),
            Student("1006", "周八", "计算机与人工智能学部", "操作系统", 80.0),
            Student("1007", "吴九", "计算机与人工智能学部", "编译原理", 86.5),
            Student("1008", "郑十", "信息科学与技术学部", "数据挖掘", 75.5),
            Student("1009", "钱十一", "电子与信息学部", "人工智能基础", 83.0),
            Student("1010", "陈十二", "计算机与人工智能学部", "Python程序设计", 89.0),
        ]
    
    #添加学生操作
    def add_student(self, student):
        self.students.append(student)
        self.save_to_file()
    #寻找学生
    def find_student(self, student_id):
        for student in self.students:
            if student.student_id == student_id:
                return student
        return None
    #删除学生
    def delete_student(self, student_id):
        self.students = [student for student in self.students if student.student_id != student_id]
        self.save_to_file()
    #更新学生
    def update_student(self, student_id, name, department, course, grade):
        student = self.find_student(student_id)
        if student:
            student.name = name
            student.department = department
            student.course = course
            student.grade = grade
            self.save_to_file()
    #学生成绩排序
    def sort_by_grade(self):
        return sorted(self.students, key=lambda x: x.grade, reverse=True)
    #显示所以学生
    def show_all_students(self):
        return self.students
    #保存文件
    def save_to_file(self):
        with open('students.dat', 'wb') as file:
            pickle.dump(self.students, file)
    #加载文件
    def load_from_file(self):
        if os.path.exists('students.dat'):
            try:
                with open('students.dat', 'rb') as file:
                    self.students = pickle.load(file)
            except (EOFError, pickle.UnpicklingError):
                # 如果文件为空或损坏,则初始化为空列表
                self.students = []
        else:
            self.students = []

class Login:
    def __init__(self, parent):
        self.parent = parent
        #默认账户
        self.username = "admin"
        #默认密码
        self.password = "password"
        # 获取屏幕的宽度和高度
        screen_width = self.parent.winfo_screenwidth()
        screen_height = self.parent.winfo_screenheight()
        # 设置窗口的尺寸
        window_width = 650
        window_height = 400
        # 计算窗口放置的位置(使其居中)
        position_top = (screen_height // 2) - (window_height // 2)-150
        position_left = (screen_width // 2) - (window_width // 2)
        # 设置窗口大小和位置
        self.parent.geometry(f"{window_width}x{window_height}+{position_left}+{position_top}")
        self.parent.title("学生信息管理系统登录")
        self.parent.config(bg="#f0f0f0")

        # 使用Frame来构建登录界面
        self.frame = ttk.Frame(self.parent, padding="30 20 30 20")
        self.frame.place(relx=0.5, rely=0.5, anchor="center")
        
        # 设置用户名标签
        ttk.Label(self.frame, text="用户名:", font=("微软雅黑", 12), background="#f0f0f0").grid(row=0, column=0, padx=10, pady=10, sticky="w")
        self.username_entry = ttk.Entry(self.frame, font=("微软雅黑", 12), width=20, justify="center")
        self.username_entry.grid(row=0, column=1, padx=10, pady=10)
        
        # 设置密码标签
        ttk.Label(self.frame, text="密码:", font=("微软雅黑", 12), background="#f0f0f0").grid(row=1, column=0, padx=10, pady=10, sticky="w")
        self.password_entry = ttk.Entry(self.frame, font=("微软雅黑", 12), show="*", width=20, justify="center")
        self.password_entry.grid(row=1, column=1, padx=10, pady=10)
        # 免密码登录
        self.login_button = ttk.Button(self.frame, text="免密登录", command=self.no_password, width=20, padding="5", 
                                       style="TButton")
        self.login_button.grid(row=2, column=0, columnspan=1, pady=20)
        
        # 登录按钮样式
        self.login_button = ttk.Button(self.frame, text="登录", command=self.login, width=20, padding="5", 
                                       style="TButton")
        self.login_button.grid(row=2, column=1, columnspan=1, pady=20)

        # 设置按钮的样式
        style = ttk.Style()
        style.configure("TButton", font=("微软雅黑", 12), padding=10, relief="flat", background="#4CAF50", foreground="white")
       

    def login(self):
        username = self.username_entry.get()
        password = self.password_entry.get()

        if username == self.username and password == self.password:
            Messagebox.show_info("登录成功", "欢迎来到学生信息管理系统!")
            self.frame.destroy()
         
            StudentManagerApp(self.parent)
        else:
            Messagebox.show_error("登录失败", "用户名或密码错误,请重新尝试!")

    def no_password(self):
        self.frame.destroy()
        StudentManagerApp(self.parent)



# 添加学生界面
class AddStudentWindow:
    def __init__(self, parent, manager):
        self.parent = parent
        self.manager = manager
        self.window = ttk.Toplevel(self.parent)
        self.window.title("添加学生")
        Position(self.parent,self.window,size=(500,450))
        self.frame = ttk.Frame(self.window, padding="30 20 30 20")
        self.frame.place(relx=0.5, rely=0.5, anchor="center",width=400,height=400)
        # 学生信息输入框
        ttk.Label(self.frame, text="学号:").grid(row=0, column=0, padx=10, pady=10)
        self.student_id_entry = ttk.Entry(self.frame)
        self.student_id_entry.grid(row=0, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="姓名:").grid(row=1, column=0, padx=10, pady=10)
        self.student_name_entry = ttk.Entry(self.frame)
        self.student_name_entry.grid(row=1, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="所在系:").grid(row=2, column=0, padx=10, pady=10)
        self.department_entry = ttk.Entry(self.frame)
        self.department_entry.grid(row=2, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="课程:").grid(row=3, column=0, padx=10, pady=10)
        self.course_entry = ttk.Entry(self.frame)
        self.course_entry.grid(row=3, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="成绩:").grid(row=4, column=0, padx=10, pady=10)
        self.grade_entry = ttk.Entry(self.frame)
        self.grade_entry.grid(row=4, column=1, padx=10, pady=10)

        self.add_button = ttk.Button(self.frame, text="添加", command=self.add_student,width=10)
        self.add_button.grid(row=5, column=0, columnspan=2, pady=10)

    def add_student(self):
        student_id = self.student_id_entry.get()
        name = self.student_name_entry.get()
        department = self.department_entry.get()
        course = self.course_entry.get()
        grade = self.grade_entry.get()

        # 验证数据
        if not self.validate_student_id(student_id):
            Messagebox.show_error(title="错误", message="学号格式不正确,请重新输入。",parent=self.window)
            return
        if not self.validate_name(name):
            Messagebox.show_error(title="错误", message="姓名不能包含字母或为空,请重新输入。",parent=self.window)
            return
        if not self.validate_department(department):
            Messagebox.show_error(title="错误", message="系别不能为空,请重新输入。",parent=self.window)
            return
        if not self.validate_course(course):
            Messagebox.show_error(title="错误", message="课程不能为空,请重新输入。",parent=self.window)
            return
        if not self.validate_grade(grade):
            Messagebox.show_error(title="错误", message="成绩无效,请输入有效的成绩(0-100)。",parent=self.window)
            return
        
        # 创建学生对象并添加
        student = Student(student_id, name, department, course, float(grade))
        self.manager.add_student(student)

        # 提示信息
        Messagebox.show_info(parent=self.window, title="添加成功", message="学生已添加")
        self.window.destroy()

    # 数据验证方法

    def validate_student_id(self, student_id):
        # 验证学号是否为数字且长度符合要求
        return student_id.isdigit()   
    
    def validate_name(self, name):
        # 验证姓名不能包含字母,只能包含数字、空格或其他特殊字符
        return bool(re.match("^[^a-zA-Z]*$", name)) and bool(name.strip())

    def validate_department(self, department):
        # 验证部门是否为空
        return bool(department.strip())

    def validate_course(self, course):
        # 验证课程是否为空
        return bool(course.strip())

    def validate_grade(self, grade):
        # 验证成绩是否为数字且在0到100之间
        try:
            grade = float(grade)
            return 0 <= grade <= 100
        except ValueError:
            return False


# 修改学生信息界面
class UpdateStudentWindow:
    def __init__(self, parent, manager):
        self.parent = parent
        self.manager = manager
        self.window = ttk.Toplevel(parent)
        self.window.title("修改学生信息")
        Position(self.parent,self.window,hposition=200,size=(400,450))
        self.frame = ttk.Frame(self.window, padding="30 20 30 20")
        self.frame.place(relx=0.5, rely=0.5, anchor="center",width=400,height=400)

        ttk.Label(self.frame, text="学号:").grid(row=0, column=0, padx=10, pady=10)
        self.student_id_entry = ttk.Entry(self.frame)
        self.student_id_entry.grid(row=0, column=1, padx=10, pady=10)

        self.find_button = ttk.Button(self.frame, text="查找", command=self.find_student,width=10)
        self.find_button.grid(row=1, column=0, columnspan=2, pady=10)

        ttk.Label(self.frame, text="姓名:").grid(row=2, column=0, padx=10, pady=10)
        self.student_name_entry = ttk.Entry(self.frame)
        self.student_name_entry.grid(row=2, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="所在系:").grid(row=3, column=0, padx=10, pady=10)
        self.department_entry = ttk.Entry(self.frame)
        self.department_entry.grid(row=3, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="课程:").grid(row=4, column=0, padx=10, pady=10)
        self.course_entry = ttk.Entry(self.frame)
        self.course_entry.grid(row=4, column=1, padx=10, pady=10)

        ttk.Label(self.frame, text="成绩:").grid(row=5, column=0, padx=10, pady=10)
        self.grade_entry = ttk.Entry(self.frame)
        self.grade_entry.grid(row=5, column=1, padx=10, pady=10)

        self.update_button = ttk.Button(self.frame, text="更新", command=self.update_student,width=10)
        self.update_button.grid(row=6, column=0, columnspan=2, pady=10)

    def find_student(self):
        student_id = self.student_id_entry.get()
        student = self.manager.find_student(student_id)

        if student:
            self.student_name_entry.delete(0, ttk.END)
            self.student_name_entry.insert(0, student.name)

            self.department_entry.delete(0, ttk.END)
            self.department_entry.insert(0, student.department)

            self.course_entry.delete(0, ttk.END)
            self.course_entry.insert(0, student.course)

            self.grade_entry.delete(0, ttk.END)
            self.grade_entry.insert(0, student.grade)
        else:
            Messagebox.show_error(parent=self.window,message="没有找到学生信息")

    def update_student(self):
        student_id = self.student_id_entry.get()
        name = self.student_name_entry.get()
        department = self.department_entry.get()
        course = self.course_entry.get()
        grade = float(self.grade_entry.get())

        self.manager.update_student(student_id, name, department, course, grade)
        Messagebox.show_info("修改信息成功!","修改学生信息",self.window)
        self.window.destroy()


# 删除学生信息界面
class DeleteStudentWindow:
    def __init__(self, parent, manager):
        self.parent = parent
        self.manager = manager
        #显示删除窗口
        self.window = ttk.Toplevel(parent)
        self.window.title("删除学生")
        #调整窗口位置和默认大小
        Position(self.parent,self.window,hposition=200,size=(400,150))
        self.frame = ttk.Frame(self.window, padding="30 20 30 20")
        self.frame.place(relx=0.5, rely=0.5, anchor="center",width=400,height=150)
        ttk.Label(self.frame, text="学号:").grid(row=0, column=0, padx=10, pady=10)
        self.student_id_entry = ttk.Entry(self.frame)
        self.student_id_entry.grid(row=0, column=1, padx=10, pady=10)

        self.delete_button = ttk.Button(self.frame, text="删除", command=self.delete_student)
        self.delete_button.grid(row=1, column=0, columnspan=2, pady=10)

    def delete_student(self):
        student_id = self.student_id_entry.get()
        #将要删除学生的学号传入管理类。
        self.manager.delete_student(student_id)
        Messagebox.show_info("删除成功", "学生信息已删除!")
        #删除当前的窗口
        self.window.destroy()

#显示所有学生信息
class ShowAllStudentsWindow:
    def __init__(self, parent, manager):
        self.parent = parent
        self.manager = manager
        # 创建一个新窗口
        self.window = ttk.Toplevel(parent)
        self.window.title("显示所有学生信息")
        # 设置窗口位置和大小
        Position(self.parent, self.window, (650, 450), hposition=300)

        # 创建Treeview控件
        self.treeview = ttk.Treeview(self.window, columns=("学号", "姓名", "学部", "课程", "成绩"), show="headings",bootstyle="primary")
        
        # 设置列标题
        self.treeview.heading("学号", text="学号")
        self.treeview.heading("姓名", text="姓名")
        self.treeview.heading("学部", text="学部")
        self.treeview.heading("课程", text="课程")
        self.treeview.heading("成绩", text="成绩")
        
        # 设置列宽度
        self.treeview.column("学号", width=100, anchor="center")
        self.treeview.column("姓名", width=100, anchor="center")
        self.treeview.column("学部", width=170, anchor="center")
        self.treeview.column("课程", width=150, anchor="center")
        self.treeview.column("成绩", width=100, anchor="center")
        
        # 滚动条
        scrollbar = ttk.Scrollbar(self.window, orient="vertical", command=self.treeview.yview)
        self.treeview.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")

        # 将Treeview放置到窗口中
        self.treeview.pack(fill=ttk.BOTH, padx=10, pady=10)

        # 显示所有学生信息
        self.show_all_students()

    def show_all_students(self):
        # 清除现有数据
        for item in self.treeview.get_children():
            self.treeview.delete(item)
         # 添加学生信息
        for student in self.manager.show_all_students():
            self.treeview.insert("", "end", values=(student.student_id, student.name, student.department, student.course, student.grade))


# 按成绩排序显示学生信息界面
class SortStudentsWindow:
    def __init__(self, parent, manager):
        self.parent = parent
        self.manager = manager
        self.window = ttk.Toplevel(parent)
        self.window.title("按成绩排序")
        Position(self.parent, self.window, (640, 450), hposition=300)
   
         # 创建Treeview控件
        self.treeview = ttk.Treeview(self.window, columns=("学号", "姓名", "学部", "课程", "成绩"), show="headings",style="darkly")
        
        # 设置列标题
        self.treeview.heading("学号", text="学号")
        self.treeview.heading("姓名", text="姓名")
        self.treeview.heading("学部", text="学部")
        self.treeview.heading("课程", text="课程")
        self.treeview.heading("成绩", text="成绩")
        
        # 设置列宽度
        self.treeview.column("学号", width=100, anchor="center")
        self.treeview.column("姓名", width=100, anchor="center")
        self.treeview.column("学部", width=170, anchor="center")
        self.treeview.column("课程", width=150, anchor="center")
        self.treeview.column("成绩", width=100, anchor="center")
        
        # 滚动条
        scrollbar = ttk.Scrollbar(self.window, orient="vertical", command=self.treeview.yview)
        self.treeview.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")

        # 将Treeview放置到窗口中
        self.treeview.pack(fill=ttk.BOTH, padx=10, pady=10)


        self.show_sorted_students()

    def show_sorted_students(self):

        sorted_students = self.manager.sort_by_grade()
        for student in sorted_students:
            self.treeview.insert("", "end", values=(student.student_id, student.name, student.department, student.course, student.grade))



# 学生信息管理系统主界面
class StudentManagerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("学生信息管理系统")
        self.root.geometry("600x700")
        
        self.style = ttk.Style(theme="superhero")  # 使用ttkbootstrap样式
        self.manager = StudentManager()
        self.frame = ttk.Frame(self.root, padding="30 20 30 20", relief="solid", borderwidth=1)
        self.frame.place(relx=0.5, rely=0.5, anchor="center", width=500, height=400)

        # 在frame中放置标签
        ttk.Label(self.frame, text="学生信息管理系统", font=("Helvetica", 24)).grid(row=0, column=0, columnspan=2, pady=20)

        # 配置frame的行列,使得每个单元格能够扩展并居中
        self.frame.grid_rowconfigure(0, weight=1)
        self.frame.grid_rowconfigure(1, weight=1)
        self.frame.grid_rowconfigure(2, weight=1)
        self.frame.grid_rowconfigure(3, weight=1)
        self.frame.grid_rowconfigure(4, weight=1)

        self.frame.grid_columnconfigure(0, weight=1)
        self.frame.grid_columnconfigure(1, weight=1)

        # 第一行按钮(添加学生,修改学生)
        self.add_button = ttk.Button(self.frame, text="添加学生", command=self.open_add_student_window, width=20, padding=10)
        self.add_button.grid(row=1, column=0, padx=10, pady=10, sticky="nsew")

        self.update_button = ttk.Button(self.frame, text="修改学生", command=self.open_update_student_window, width=20, padding=10)
        self.update_button.grid(row=1, column=1, padx=10, pady=10, sticky="nsew")

        # 第二行按钮(删除学生,按成绩排序)
        self.delete_button = ttk.Button(self.frame, text="删除学生", command=self.open_delete_student_window, width=20, padding=10)
        self.delete_button.grid(row=2, column=0, padx=10, pady=10, sticky="nsew")

        self.sort_button = ttk.Button(self.frame, text="按成绩排序", command=self.open_sort_students_window, width=20, padding=10)
        self.sort_button.grid(row=2, column=1, padx=10, pady=10, sticky="nsew")

        # 第三行按钮(显示所有学生,保存信息)
        self.show_button = ttk.Button(self.frame, text="显示所有学生", command=self.open_show_all_students_window, width=20, padding=10)
        self.show_button.grid(row=3, column=0, padx=10, pady=10, sticky="nsew")

        self.save_button = ttk.Button(self.frame, text="保存信息", command=self.save_info, width=20, padding=10)
        self.save_button.grid(row=3, column=1, padx=10, pady=10, sticky="nsew")

        # 第四行按钮(退出系统)
        self.exit_button = ttk.Button(self.frame, text="退出系统", command=self.root.quit, width=20, padding=10)
        self.exit_button.grid(row=4, column=0, columnspan=2, padx=10, pady=10, sticky="nsew")
        #添加学生
    def open_add_student_window(self):
        AddStudentWindow(self.root, self.manager)
        #修改学生
    def open_update_student_window(self):
        UpdateStudentWindow(self.root, self.manager)
        #删除学生
    def open_delete_student_window(self):
        DeleteStudentWindow(self.root, self.manager)
        #成绩排序
    def open_sort_students_window(self):
        SortStudentsWindow(self.root, self.manager)
        #显示所有学生
    def open_show_all_students_window(self):
        ShowAllStudentsWindow(self.root, self.manager)
        #保存信息
    def save_info(self):
        self.manager.save_to_file()
        Messagebox.show_info("保存成功", "学生信息已成功保存到文件。")


if __name__ == "__main__":
    root = ttk.Window(position=(700,200),size=(500,400),title="学生管理系统登录")
    login_page = Login(root)
    root.mainloop()

 前面展示的各个功能,比如添加学生,删除,修改等实际是上面这个类完成的,是学生管理系统的核心。


五、总结

这个学生信息管理系统比较简单,功能不多,外形没有过多的设计,以至于看起来有些单调,但很适合刚接触python GUI库的学生学习。

ttkbootstrap库功能很强,我展示的内容只是一小部分,如果有同学感兴趣,可以去官网学习。

网址:

https://ttkbootstrap.readthedocs.io/

求关注收藏!

作者:东婉漓

物联沃分享整理
物联沃-IOTWORD物联网 » 基于 Python ttkbootstrap 库的简单学生管理系统实现。

发表回复