python之学生信息管理系统


前言

本实验采用的是python中的thinter来实现图形界面的设计(GUI),将数据存放在students.json文件中,利用python来作为开发工具。本系统同时具有用户登录页面,还具有信息录入以及对信息的管理功能(增删改查)。


一、登录界面LoginPage

首先通过tkinter模块通过root建立根窗口并将这个窗口赋给master,并且给这个根窗口建立标题以及它的窗口大小。然后对该根目录进行布局,分别定义账户以及密码标签,并且在这两个标签后用Entry布局输入框。将需要输入的账户和密码定义为字符串变量对象。然后在这两个标签下方建立两个按钮,设置文本为登录与退出。
代码如下:

from tkinter import *
from tkinter import messagebox
from Databases import db
from MainPage import MainPage


class LaginPage:
    def __init__(self,master):
        self.root = master
        self.root.title("学生信息管理系统")
        self.root.geometry("300x180")

        self.username = StringVar()
        self.password = StringVar()

        self.page=Frame(root)
        self.page.pack()

        Label(self.page).grid(row=0,column=0)
        Label(self.page,text="账户").grid(row=1,column=1)
        Entry(self.page,textvariable=self.username).grid(row=1,column=2)

        Label(self.page,text="密码").grid(row=2,column=1,pady=10)
        Entry(self.page,textvariable=self.password).grid(row=2,column=2)

        Button(self.page,text="登录",command=self.login).grid(row=3,column=1,pady=10)
        Button(self.page,text="退出",command=self.page.quit).grid(row=3,column=2)

    def login(self):
        xingming = self.username.get()
        mima = self.password.get()
        flag,message = db.check_login(xingming,mima)
        if flag:
            self.page.destroy()
            MainPage(self.root)
        else:
            messagebox.showwarning(message=message)

if __name__ == '__main__':
    root = Tk()
    LaginPage(master=root)
    root.mainloop()

二、功能页面框架MainPage

设置相关布局

代码如下:

import tkinter as tk
from views import ChangeFrame, InsertFrame, DeleteFrame, AboutFrame, SearchFrame, PaixuFrame


class MainPage:
    def __init__(self, master: tk.Tk):
        self.root = master
        self.root.title("学生信息管理系统")
        self.root.geometry("600x400")
        self.creat_page()

    def creat_page(self):
        self.insert_frame = InsertFrame(self.root)
        self.change_frame = ChangeFrame(self.root)
        self.delete_frame = DeleteFrame(self.root)
        self.search_frame = SearchFrame(self.root)
        self.paixu_frame = PaixuFrame(self.root)
        self.about_frame = AboutFrame(self.root)

        menu = tk.Menu(self.root)
        menu.add_command(label="录入", command=self.show_insert)
        menu.add_command(label="打印", command=self.show_search)
        menu.add_command(label="删除", command=self.show_delete)
        menu.add_command(label="修改", command=self.show_change)
        menu.add_command(label="排序", command=self.show_paixu)
        menu.add_command(label="关于", command=self.show_about)
        self.root["menu"] = menu

    def show_insert(self):
        self.insert_frame.pack()
        self.about_frame.pack_forget()
        self.change_frame.pack_forget()
        self.delete_frame.pack_forget()
        self.search_frame.pack_forget()
        self.paixu_frame.pack_forget()

    def show_about(self):
        self.insert_frame.pack_forget()
        self.about_frame.pack()
        self.change_frame.pack_forget()
        self.delete_frame.pack_forget()
        self.search_frame.pack_forget()
        self.paixu_frame.pack_forget()

    def show_change(self):
        self.insert_frame.pack_forget()
        self.change_frame.pack()
        self.about_frame.pack_forget()
        self.delete_frame.pack_forget()
        self.search_frame.pack_forget()
        self.paixu_frame.pack_forget()

    def show_delete(self):
        self.insert_frame.pack_forget()
        self.about_frame.pack_forget()
        self.change_frame.pack_forget()
        self.delete_frame.pack()
        self.search_frame.pack_forget()
        self.paixu_frame.pack_forget()

    def show_search(self):
        self.insert_frame.pack_forget()
        self.about_frame.pack_forget()
        self.change_frame.pack_forget()
        self.delete_frame.pack_forget()
        self.search_frame.pack()
        self.paixu_frame.pack_forget()

    def show_paixu(self):
        self.insert_frame.pack_forget()
        self.about_frame.pack_forget()
        self.change_frame.pack_forget()
        self.delete_frame.pack_forget()
        self.search_frame.pack_forget()
        self.paixu_frame.pack()


if __name__ == '__main__':
    root = tk.Tk()
    MainPage(master=root)
    root.mainloop()

三、功能的实现views

该部分对前面主页面的相关功能进行相关的实现,同时会和一些数据进行连接,连接的类下面会进行介绍,接下来把相关增删改查的相关功能代码介绍如下:

import copy
import json
import tkinter as tk
from tkinter import ttk
from Databases import db


class InsertFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.id = tk.StringVar()
        self.name = tk.StringVar()
        self.chinese = tk.StringVar()
        self.math = tk.StringVar()
        self.english = tk.StringVar()
        self.zong = tk.StringVar()
        self.status = tk.StringVar()
        self.create_page()

    def create_page(self):
        tk.Label(self).grid(row=0, pady=10)

        tk.Label(self, text='学 号:').grid(row=1, column=1, pady=10)
        tk.Entry(self, textvariable=self.id).grid(row=1, column=2, pady=10)

        tk.Label(self, text='姓 名:').grid(row=2, column=1, pady=10)
        tk.Entry(self, textvariable=self.name).grid(row=2, column=2, pady=10)

        tk.Label(self, text='语 文:').grid(row=3, column=1, pady=10)
        tk.Entry(self, textvariable=self.chinese).grid(row=3, column=2, pady=10)

        tk.Label(self, text='数 学:').grid(row=4, column=1, pady=10)
        tk.Entry(self, textvariable=self.math).grid(row=4, column=2, pady=10)

        tk.Label(self, text='英 语:').grid(row=5, column=1, pady=10)
        tk.Entry(self, textvariable=self.english).grid(row=5, column=2, pady=10)

        tk.Button(self, text='录入', command=self.recode_info).grid(row=6, column=2, pady=10)

        tk.Label(self, textvariable=self.status).grid(row=7, column=2, pady=10, sticky=tk.E)

    def recode_info(self):
        for stu in db.students:
            if stu['id'] == self.id.get():
                self.status.set('学号存在,录入数据失败')
                return
        if self.id.get() == '' or self.name.get() == '' or self.chinese.get()=='' or self.math.get() == '' or self.english.get() == '':
            self.status.set('输入信息有误,录入数据失败')
            return
        stu = {
            "id": self.id.get(),
            "name": self.name.get(),
            "chinese": int(self.chinese.get()),
            "math": int(self.math.get()),
            "english": int(self.english.get()),
            "zong": int(self.chinese.get()) + int(self.math.get()) + int(self.english.get())}
        self.id.set('')
        self.name.set('')
        self.chinese.set('')
        self.math.set('')
        self.english.set('')
        self.zong.set('')

        db.insert(stu)
        with open('student.json', 'w', encoding='utf-8') as dump_f:
            json.dump(db.students, dump_f, ensure_ascii=False)
        self.status.set('录入数据成功')


class AboutFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        tk.Label(self, text='关于作品:学生信息管理系统').pack()
        tk.Label(self, text='制作时间:2022年5月').pack()
        tk.Label(self, text='版权所有:20软一').pack()


class SearchFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.table_view = tk.Frame()
        self.table_view.pack()

        self.create_page()

    def create_page(self):
        columns = ("id", "name", "chinese", "math", "english", "zong")
        columns_values = ("学号", "姓名", "语文", "数学", "英语", "总分")
        self.tree_view = ttk.Treeview(self, show="headings", columns=columns)
        self.tree_view.column("id", width=80, anchor="center")
        self.tree_view.column("name", width=80, anchor="center")
        self.tree_view.column("chinese", width=80, anchor="center")
        self.tree_view.column("math", width=80, anchor="center")
        self.tree_view.column("english", width=80, anchor="center")
        self.tree_view.column("zong", width=80, anchor="center")
        self.tree_view.heading("id", text="学号")
        self.tree_view.heading("name", text="姓名")
        self.tree_view.heading("chinese", text="语文")
        self.tree_view.heading("math", text="数学")
        self.tree_view.heading("english", text="英语")
        self.tree_view.heading("zong", text="总分")
        self.tree_view.pack(fill=tk.BOTH, expand=True)
        self.show_dataframe()

        tk.Button(self, text='刷新数据', command=self.show_dataframe).pack(anchor=tk.E, pady=5)

    def show_dataframe(self):
        # 刷新
        for _ in map(self.tree_view.delete, self.tree_view.get_children('')):
            pass
        students = db.stu()
        index = -1
        for stu in students:
            self.tree_view.insert('', index + 1, values=(
                stu['id'], stu['name'], stu['chinese'], stu['math'], stu['english'], stu['zong']
            ))


class PaixuFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.table_view = tk.Frame()
        self.table_view.pack()

        self.create_page()

    def create_page(self):
        columns = ("id", "name", "chinese", "math", "english", "zong")
        columns_values = ("学号", "姓名", "语文", "数学", "英语", "总分")
        self.tree_view = ttk.Treeview(self, show="headings", columns=columns)
        self.tree_view.column("id", width=80, anchor="center")
        self.tree_view.column("name", width=80, anchor="center")
        self.tree_view.column("chinese", width=80, anchor="center")
        self.tree_view.column("math", width=80, anchor="center")
        self.tree_view.column("english", width=80, anchor="center")
        self.tree_view.column("zong", width=80, anchor="center")
        self.tree_view.heading("id", text="学号")
        self.tree_view.heading("name", text="姓名")
        self.tree_view.heading("chinese", text="语文")
        self.tree_view.heading("math", text="数学")
        self.tree_view.heading("english", text="英语")
        self.tree_view.heading("zong", text="总分")
        self.tree_view.pack(fill=tk.BOTH, expand=True)
        self.show1_dataframe()

        tk.Button(self, text='刷新数据', command=self.show1_dataframe).pack(anchor=tk.E, pady=5)

    def show1_dataframe(self):
        # 刷新
        for _ in map(self.tree_view.delete, self.tree_view.get_children('')):
            pass
        students=copy.deepcopy(db.students)
        students.sort(key = lambda x:x["zong"])
        index = -1
        for stu in students:
            self.tree_view.insert('', index + 1, values=(
                stu['id'], stu['name'], stu['chinese'], stu['math'], stu['english'], stu['zong']
            ))


class ChangeFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.id = tk.StringVar()
        self.name = tk.StringVar()
        self.chinese = tk.StringVar()
        self.math = tk.StringVar()
        self.english = tk.StringVar()
        self.zong=tk.StringVar()
        self.status = tk.StringVar()
        self.create_page()

    def create_page(self):
        tk.Label(self).grid(row=0, pady=10)

        tk.Label(self, text='学 号:').grid(row=1, column=1, pady=10)
        tk.Entry(self, textvariable=self.id).grid(row=1, column=2, pady=10)

        tk.Label(self, text='姓 名:').grid(row=2, column=1, pady=10)
        tk.Entry(self, textvariable=self.name).grid(row=2, column=2, pady=10)

        tk.Label(self, text='语 文:').grid(row=3, column=1, pady=10)
        tk.Entry(self, textvariable=self.chinese).grid(row=3, column=2, pady=10)

        tk.Label(self, text='数 学:').grid(row=4, column=1, pady=10)
        tk.Entry(self, textvariable=self.math).grid(row=4, column=2, pady=10)

        tk.Label(self, text='英 语:').grid(row=5, column=1, pady=10)
        tk.Entry(self, textvariable=self.english).grid(row=5, column=2, pady=10)

        tk.Button(self, text='查询', command=self.search_user).grid(row=6, column=1, pady=10)
        tk.Button(self, text='修改', command=self.change_user).grid(row=6, column=2, pady=10)

        tk.Label(self, textvariable=self.status).grid(row=7, column=2, pady=10, sticky=tk.E)

    def search_user(self):
        flag, info = db.search_username(self.id.get())
        if flag:
            self.id.set(info['id'])
            self.name.set(info['name'])
            self.chinese.set(info['chinese'])
            self.math.set(info['math'])
            self.english.set(info['english'])
            self.status.set('数据查询成功')
        else:
            self.status.set(info)

    def change_user(self):
        stu = {"id": self.id.get(),
               "name": self.name.get(),
               "chinese": int(self.chinese.get()),
               "math": int(self.math.get()),
               "english": int(self.english.get()),
               "zong": int(self.chinese.get()) + int(self.math.get()) + int(self.english.get())}
        self.id.set('')
        self.name.set('')
        self.chinese.set('')
        self.math.set('')
        self.english.set('')
        self.zong.set('')
        db.update(stu)
        self.status.set('修改数据成功')


class DeleteFrame(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.username = tk.StringVar()
        self.status = tk.StringVar()
        tk.Label(self, text='请输入需要删除的学号').pack()
        tk.Entry(self, textvariable=self.username).pack()
        tk.Button(self, text='删除', command=self.delete).pack()
        tk.Label(self, textvariable=self.status).pack()

    def delete(self):
        username = self.username.get()
        flag, message = db.delete_username(username)
        self.status.set(message)

四、数据连接Databases

该类是对前面主页面中的功能进行相关的实现,同时也将数据与两个json文件相连起来,可以起到文件的保存作用,在用户录入学生的相关信息后可以保存在students类中,同时删除了之后就会在这个文件中进行相应的删除,,同时这个类与登录界面也有着相互联系,与user文件相关联,可以读取user文件中的信息,来进行匹配登录。相关代码如下:

import json

class Databases:
    def __init__(self):
        self.users = json.loads(open('users.json',mode='r',encoding='utf-8').read())
        self.students = json.loads(open('student.json',mode='r',encoding='utf-8').read())

    def check_login(self,username,password):
        for user in self.users:
            if username == user["username"]:
                if password == user["password"]:
                    return True,'登录成功'
                else:
                    return False,'登录失败,密码错误'
        return False,'登陆失败,用户不存在'

    def stu(self):
        return self.students

    def insert(self,student):
        self.students.append(student)

    def delete_username(self, id):
        for stu in self.students:
            if stu['id'] ==id:
                self.students.remove(stu)
                with open('student.json', 'w', encoding='utf-8') as dump_f:
                    json.dump(self.students, dump_f, ensure_ascii=False)
                return True,f'{id}用户删除成功'
        return False,f'{id}用户不存在'

    def search_username(self, id):
        for stu in self.students:
            if stu['id'] ==id:
                return True,stu
        return False,f'{id}用户不存在'

    def update(self,stu):
        for student in self.students:
            if student['id'] == stu['id']:
                student.update(stu)
                with open('student.json', 'w', encoding='utf-8') as dump_f:
                    json.dump(self.students, dump_f, ensure_ascii=False)
                return True,f'{stu["id"]}用户数据修改成功'
        return False,f'{stu["name"]}用户不存在'


db = Databases()

if __name__ == '__main__':
    print(db.check_login('bxp','123456'))
    print(db.stu())

文件students.json的初始化:
[{“id”: “10001”, “name”: “张三”, “chinese”: 70, “math”: 80, “english”: 70, “zong”: 220}, {“id”: “10002”, “name”: “李四”, “chinese”: 93, “math”: 85, “english”: 60, “zong”: 238}, {“id”: “10003”, “name”: “王五”, “chinese”: 99, “math”: 85, “english”: 60, “zong”: 244}]
文件user.json的初始化:
[{“username”: “bxp”,“password”: “123456”}]

总结

该学生管理系统其实并不是特别困难,就是通过GUI对这个界面进行相关的布局美化操作还需有待提高,同时登录界面的密码显示也可以进行相关的屏蔽处理,但是这个系统也都是还可以进行相关的学生信息的增删改查功能的。

  • 1
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值