python学生管理系统(tkinter、pickle、pandas)

学生管理系统

import os
import pickle # pickle库 用于保存和加载文件中的数据
import pandas as pd
import operator # 比较两个字典是否相等
import random
import re
import webbrowser # 访问网址
'''
待扩展内容1 实现子窗口关闭时,父窗口无法使用
待扩展内容2 可增加学科的功能
# 数据结构 {stu_id: {'name': '张三', 'subjects':{} } }
# subjects: {math: 100, chinese: 100, english: 99......}
'''
import tkinter as tk # tkinter库 用于显示操作界面(GUI)
from tkinter import messagebox
from tkinter import simpledialog
from tkinter import filedialog
from tkinter import ttk


class Student():
    firstName = ["张", "李", "王", "陈", "叶", "鲁", "詹", "曹", "苏", "朱", "孔", "宋", "谢", "沈", "木", "唐", "留", "曾", "秋", "夏", "春", "冬", "林", "威", "右", "左"]
    lastName = ["兆鹏", "思雨", "一飞", "淼", "峰", "成功", "天佑", "轼", "子强", "凌云", "慈欣", "蝉", "宗元", "适", "伯伦", "匡胤", "布斯", "破伦", "逸飞", "善成", "保成", "殷武", "嘉佑"]
    def process(self, num):
        num_str = str(num)
        while len(num_str) < 5:
            num_str = "0" + num_str
        return num_str
    def randomName(self):
        return random.choice(Student.firstName) + random.choice(Student.lastName)
    def __init__(self):
        self.stu_no = str(random.randint(2020, 2024)) + 'b' + self.process(random.randint(1, 100000))
        self.name = self.randomName()
        self.python = random.randint(50, 100)
        self.english = random.randint(40, 90)
        self.math = random.randint(30, 100)

class ValidInput:

    
    START_ROW = 0
    IS_VALID = True # 需要在外部重置
    BACK_DATA = []
    def __init__(self, root, label_text, pattern, box_num, callback, former_data = ""):
        self.root = root
        self.box_num = box_num
        self.pattern = pattern
        self.callback = callback
        self.cur_row = ValidInput.START_ROW

        self.label = ttk.Label(root, text = label_text)
        self.label.grid(row = ValidInput.START_ROW, column = 0, padx = 20, pady = 20)

        self.input_entry = ttk.Entry(root)
        self.input_entry.grid(row = ValidInput.START_ROW, column = 1, padx = 20, pady = 20)
        self.input_entry.insert('0', former_data)

        self.error_label = tk.Label(root, text="", fg="red", width = 20)
        self.error_label.grid(row = ValidInput.START_ROW + 1, column = 1)
        ValidInput.START_ROW += 2

    def validate_input(self):
        input_text = self.input_entry.get()
        if re.match(self.pattern, input_text):
            #print("accord")
            self.error_label.config(text="", fg="red")
            ValidInput.BACK_DATA.append(input_text)
            if self.cur_row + 2 == self.box_num * 2 and ValidInput.IS_VALID:
                self.callback(ValidInput.BACK_DATA)
        else:
            self.error_label.config(text="请输入合法的数据", fg="red")
            ValidInput.IS_VALID = False

class CreateOrUpdateStu():
    # 回调函数
    def process(self, item):
        # 执行回调函数,将参数传入上级
        if self.status == 'create':
            self.callback(item)
        elif self.status == 'edit':
            self.callback(item, self.former_data[0])
        self.root.destroy()
    def confirm(self, stu_no, name, python, english, math):
        stu_no.validate_input()
        name.validate_input()
        python.validate_input()
        english.validate_input()
        math.validate_input()
        ValidInput.IS_VALID = True
        ValidInput.BACK_DATA = []
    def on_closing(self):
        ValidInput.START_ROW = 0 # todo 需要做赋值的地方
    def __init__(self, callback, former_data = []):

        # 编辑时以前的数据
        self.former_data = former_data
        if former_data == []:
            self.status = "create"
        else:
            self.status = "edit"

        # 回调函数
        self.callback = callback

        # 创建主窗口
        root = tk.Tk()
        root.protocol("WM_DELETE_WINDOW", self.on_closing())
        self.root = root
        # 设置窗口标题
        title_text = "新增" if self.status == "create" else "编辑"
        root.title(title_text)

        # 设置窗口大小
        #root.geometry("300x200")

        '''
        正则匹配(注:r""语法可以创建原始字符串(raw string),原始字符串中的反斜杠不会被转义):
        0-100之间的整数: ^(0|[1-9]\d?|100)$
        整数: ^-?\d+$
        0-100之间的数字,可以是小数或者整数: ^(0.\d{1,2}|[1-9]\d?(.\d{1,2})?|100|100.0|100.00)$
        不为空的字符串: ^.+$
        小数: ^-?\d+.\d+$
        2-4个汉字: ^[\u4e00-\u9fa5]{2,4}$
        学号20XXbXXXXX: "^20[0-9]{2}b(?!0{5})\d{5}$"
        '''
        # 创建标签和输入框
        # 匹配学号20XXbXXXXX
        validator_stu_no = ValidInput(root, "学号(20XXbXXXXX):", "^20[0-9]{2}b(?!0{5})\d{5}$", 5, self.process, self.former_data[1] if self.former_data else "")
        # 匹配2-4个汉字
        validator_name = ValidInput(root, "姓名(2-4个汉字):", "^[\u4e00-\u9fa5]{2,4}$", 5, self.process, self.former_data[2] if self.former_data else "")
        # 匹配0-100之间的整数
        validator_python = ValidInput(root, "python成绩(0-100):", "^(0|[1-9]\d?|100)$", 5, self.process, self.former_data[3] if self.former_data else "")
        # 匹配0-100之间的整数
        validator_english = ValidInput(root, "英语成绩(0-100):", "^(0|[1-9]\d?|100)$", 5, self.process, self.former_data[4] if self.former_data else "")
        # 匹配0-100之间的整数
        validator_math = ValidInput(root, "数学成绩(0-100):", "^(0|[1-9]\d?|100)$", 5, self.process, self.former_data[5] if self.former_data else "")


        confirm_button = ttk.Button(root, text = "确定", command = lambda: self.confirm(validator_stu_no, validator_name, validator_python, validator_english, validator_math))
        confirm_button.grid(row = 5 * 2, column = 0, padx = 20, pady = 20)

        cancel_button = ttk.Button(root, text = "取消", command = root.destroy)
        cancel_button.grid(row = 5 * 2, column = 1, padx = 20, pady = 20)

        # 进入消息循环
        root.mainloop()


class EditProperty:
    def __init__(self, properties, properties_name, callback):
        self.root = tk.Tk()
        self.callback = callback
        self.properties = properties
        self.properties_name = properties_name
        self.root.title("编辑字段")
        self.overwrite_var = tk.IntVar(master = self.root)

        self.label = ttk.Label(self.root, text="全部字段:")
        self.label.grid(row = 0, column = 0, padx = 20, pady = 20)
        # 表格布局
        columns = ['property', 'property_name']
        table = ttk.Treeview(
                master = self.root,  # 父容器
                height = 9,  # 表格显示的行数,height行
                columns = columns,  # 显示的列
                show='headings',  # 隐藏首列
                )
        self.table = table
        # 定义表头
        table.heading('property', text='字段', anchor='w')
        table.heading('property_name', text='字段名称', anchor='w')
        # 定义列
        table.column('property', width=140, anchor='w')
        table.column('property_name', width=140, anchor='w')
        # 定位
        table.grid(row = 1, column = 0, columnspan = 4)
        for i in range(len(properties)):
            table.insert("", "end", values = (properties[i], properties_name[i]))
        


        # 编辑 向上 向下 删除
        self.confirm_button = ttk.Button(self.root, text = "新增", command = self.handleCreate)
        self.confirm_button.grid(row = 2, column = 0, padx = 20, pady = 20)

        
        self.cancel_button = ttk.Button(self.root, text = "删除", command = self.handleDelete)
        self.cancel_button.grid(row = 2, column = 1, padx = 20, p
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值