基于python的师生一体化学生信息管理系统——python期末设计!!!

系统介绍

该系统使用python语言进行程序设计,设计的主要内容可概括为以下几点:师生一体化学生信息管理系统,首先由管理员(教师)增加、删除、修改、查找、导出学生信息(excel表格的形式),再有学生的功能不同于管理员,管理员还可以根据管理员的账号更改自己的密码和新增新的管理员。学生通过自己的学号和赋予的初始密码进行登录,学生可以通过本系统来查成绩、查询及修改个人账号的密码。

系统实现效果

首页
在这里插入图片描述
学生登陆界面,管理员界面大同小异
在这里插入图片描述
学生信息界面
在这里插入图片描述
管理员操作界面
在这里插入图片描述

系统使用的python库和python解释器

python库

系统配置

MySQL:mysql8.0
navicat:navicat 12
Pycharm:2021.2版本

主要程序代码

代码都有关键注释!!!!!

import pymysql
import xlwt #导出excel
import importlib,sys
importlib.reload(sys)
from tkinter import ttk
import tkinter as tk
from PIL import ImageTk, Image # 背景图片
import tkinter.font as tkFont
from tkinter import *  # 图形界面库
import tkinter.messagebox as messagebox  # 弹窗

# 初始化初始系统界面元素
class StartPage:
    def __init__(self, parent_window):
        parent_window.destroy()  # 销毁子界面

        self.window = tk.Tk()  # 初始框的声明
        self.window.title('学生信息管理系统')
        self.window.geometry('300x470')
        #防止用户自主调整窗口大小尺寸
        self.window.resizable(0,0)


        label = Label(self.window, text="学生信息管理系统", font=("Verdana", 20))
        label.pack(pady=100)  # pady=100 界面的长度

        Button(self.window, text="管理员登陆", font=tkFont.Font(size=16), command=lambda: AdminPage(self.window), width=30,
               height=2,
               fg='white', bg='gray', activebackground='black', activeforeground='white').pack()
        Button(self.window, text="学生登陆", font=tkFont.Font(size=16), command=lambda: StudentPage(self.window), width=30,
               height=2, fg='white', bg='gray', activebackground='black', activeforeground='white').pack()
        Button(self.window, text="账号系统", font=tkFont.Font(size=16), command=lambda: AboutPage(self.window),
               width=30,
               height=2,
               fg='white', bg='gray', activebackground='black', activeforeground='white').pack()
        Button(self.window, text='退出系统', height=2, font=tkFont.Font(size=16), width=30, command=self.window.destroy,
               fg='white', bg='gray', activebackground='black', activeforeground='white').pack()

        self.window.mainloop()  # 主消息循环


# 管理员登陆及退出页面
class AdminPage:
    def __init__(self, parent_window):
        parent_window.destroy()  # 销毁主界面

        self.window = tk.Tk()  # 初始框的声明
        self.window.title('管理员登陆页面')
        self.window.geometry('300x450')
        # 防止用户调整尺寸
        self.window.resizable(0, 0)

        label = tk.Label(self.window, text='管理员登陆', bg='green', font=('Verdana', 20), width=30, height=2)
        label.pack()

        Label(self.window, text='管理员账号:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_username = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')
        self.admin_username.pack()

        Label(self.window, text='管理员密码:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_pass = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory', show='*')
        self.admin_pass.pack()

        Button(self.window, text="登陆", width=8, font=tkFont.Font(size=12), command=self.login).pack(pady=40)
        Button(self.window, text="返回首页", width=8, font=tkFont.Font(size=12), command=self.back).pack()

        self.window.protocol("WM_DELETE_WINDOW", self.back)  # 捕捉右上角关闭点击
        self.window.mainloop()  # 进入消息循环

    # 管理员登陆
    def login(self):
        print(str(self.admin_username.get()))
        print(str(self.admin_pass.get()))
        admin_pass = None

        # 数据库操作 查询管理员表
        db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456') # 打开数据库连接
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "SELECT * FROM admin_login_k WHERE admin_id = '%s'" % (self.admin_username.get())  # SQL 查询语句
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 获取所有记录列表
            results = cursor.fetchall()
            for row in results:
                admin_id = row[0]
                admin_pass = row[1]
                # 打印结果
                print("admin_id=%s,admin_pass=%s" % (admin_id, admin_pass))
        except:
            print("Error: unable to fecth data")
            messagebox.showinfo('警告!', '用户名或密码不正确!')
        db.close()  # 关闭数据库连接

        print("正在登陆管理员管理界面")
        print("self", self.admin_pass)
        print("local", admin_pass)

        if self.admin_pass.get() == admin_pass:
            AdminManage(self.window)  # 进入管理员操作界面
        else:
            messagebox.showinfo('警告!', '用户名或密码不正确!')

    # 管理员退出
    def back(self):
        StartPage(self.window)  # 显示主窗口 销毁本窗口


# 学生登陆及退出页面
class StudentPage:
    def __init__(self, parent_window):
        parent_window.destroy()  # 销毁主界面

        self.window = tk.Tk()  # 初始框的声明
        self.window.title('学生登陆')
        self.window.geometry('300x450')
        # 防止用户调整尺寸
        self.window.resizable(0, 0)

        label = tk.Label(self.window, text='学生登陆', bg='pink', font=('Verdana', 20), width=30, height=2)
        label.pack()

        Label(self.window, text='学生账号:', font=tkFont.Font(size=14)).pack(pady=25)
        self.student_id = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')
        self.student_id.pack()

        Label(self.window, text='学生密码:', font=tkFont.Font(size=14)).pack(pady=25)
        self.student_pass = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory', show='*')
        self.student_pass.pack()

        Button(self.window, text="登陆", width=8, font=tkFont.Font(size=12), command=self.login).pack(pady=40)
        Button(self.window, text="返回首页", width=8, font=tkFont.Font(size=12), command=self.back).pack()

        self.window.protocol("WM_DELETE_WINDOW", self.back)  # 捕捉右上角关闭点击
        self.window.mainloop()  # 进入消息循环

    def login(self):
        print(str(self.student_id.get()))
        print(str(self.student_pass.get()))
        stu_pass = None

        # 数据库操作 查询管理员表
        db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')  # 打开数据库连接
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "SELECT * FROM stu_login_k WHERE stu_id = '%s'" % (self.student_id.get())  # SQL 查询语句
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 获取所有记录列表
            results = cursor.fetchall()
            for row in results:
                stu_id = row[0]
                stu_pass = row[1]
                # 打印结果
                print("stu_id=%s,stu_pass=%s" % (stu_id, stu_pass))
        except:
            print("Error: unable to fecth data")
            messagebox.showinfo('警告!', '用户名或密码不正确!')
        db.close()  # 关闭数据库连接

        print("正在登陆学生信息查看界面")
        print("self", self.student_pass.get())
        print("local", stu_pass)

        if self.student_pass.get() == stu_pass:
            StudentView(self.window, self.student_id.get())  # 进入学生信息查看界面
        else:
            messagebox.showinfo('警告!', '用户名或密码不正确!')

    def back(self):
        StartPage(self.window)  # 显示主窗口 销毁本窗口


# 管理员操作界面
class AdminManage:
    def __init__(self, parent_window):
        parent_window.destroy()  # 销毁主界面

        self.window = Tk()  # 初始框的声明
        self.window.title('管理员操作界面')
        # 防止用户调整尺寸
        self.window.resizable(0, 0)

        # 整体区域定位
        self.frame_left_top = tk.Frame(width=300, height=200)
        self.frame_right_top = tk.Frame(width=200, height=200)
        self.frame_center = tk.Frame(width=500, height=400)
        self.frame_bottom = tk.Frame(width=650, height=50)

        # 定义下方中心列表区域
        self.columns = ("学号", "姓名", "性别", "年龄","成绩")
        self.tree = ttk.Treeview(self.frame_center, show="headings", height=18, columns=self.columns)
        self.vbar = ttk.Scrollbar(self.frame_center, orient=VERTICAL, command=self.tree.yview)
        # 定义树形结构与滚动条
        self.tree.configure(yscrollcommand=self.vbar.set)

        # 表格的标题
        self.tree.column("学号", width=100, anchor='center')  # 表示列,不显示
        self.tree.column("姓名", width=100, anchor='center')
        self.tree.column("性别", width=100, anchor='center')
        self.tree.column("年龄", width=100, anchor='center')
        self.tree.column("成绩", width=100, anchor='center')

        # 调用方法获取表格内容插入
        self.tree.grid(row=0, column=0, sticky=NSEW)
        self.vbar.grid(row=0, column=1, sticky=NS)

        self.id = []
        self.name = []
        self.gender = []
        self.age = []
        self.score = []
        # 打开数据库连接
        db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "SELECT * FROM student_k"  # SQL 查询所有学生信息
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 获取所有记录列表
            results = cursor.fetchall()
            for row in results:
                self.id.append(row[0])
                self.name.append(row[1])
                self.gender.append(row[2])
                self.age.append(row[3])
                self.score.append(row[4])
            print(self.id)
            print(self.name)
            print(self.gender)
            print(self.age)
            print(self.score)
        except:
            print("Error: unable to fetch data")
            messagebox.showinfo('警告!', '数据库连接失败!')
        db.close()  # 关闭数据库连接

        print("test***********************")
        for i in range(min(len(self.id), len(self.name), len(self.gender), len(self.age), len(self.score))):  # 写入数据
            self.tree.insert('', i, values=(self.id[i], self.name[i], self.gender[i], self.age[i], self.score[i]))

        for col in self.columns:  # 绑定函数,使表头可排序
            self.tree.heading(col, text=col,
                              command=lambda _col=col: self.tree_sort_column(self.tree, _col, False))

        # 定义顶部区域
        # 定义左上方区域
        self.top_title = Label(self.frame_left_top, text="学生信息:", font=('Verdana', 10))
        self.top_title.grid(row=0, column=0, columnspan=2, sticky=NSEW, padx=50, pady=10)

        self.left_top_frame = tk.Frame(self.frame_left_top)
        self.var_id = StringVar()  # 声明学号
        self.var_name = StringVar()  # 声明姓名
        self.var_gender = StringVar()  # 声明性别
        self.var_age = StringVar()  # 声明年龄
        self.var_score = StringVar()  # 声明成绩
        # 学号
        self.right_top_id_label = Label(self.frame_left_top, text="学号:", font=('Verdana', 15))
        self.right_top_id_entry = Entry(self.frame_left_top, textvariable=self.var_id, font=('Verdana', 15))
        self.right_top_id_label.grid(row=1, column=0)  # 位置设置
        self.right_top_id_entry.grid(row=1, column=1)
        # 姓名
        self.right_top_name_label = Label(self.frame_left_top, text="姓名:", font=('Verdana', 15))
        self.right_top_name_entry = Entry(self.frame_left_top, textvariable=self.var_name, font=('Verdana', 15))
        self.right_top_name_label.grid(row=2, column=0)  # 位置设置
        self.right_top_name_entry.grid(row=2, column=1)
        # 性别
        self.right_top_gender_label = Label(self.frame_left_top, text="性别:", font=('Verdana', 15))
        self.right_top_gender_entry = Entry(self.frame_left_top, textvariable=self.var_gender,
                                            font=('Verdana', 15))
        self.right_top_gender_label.grid(row=3, column=0)  # 位置设置
        self.right_top_gender_entry.grid(row=3, column=1)
        # 年龄
        self.right_top_gender_label = Label(self.frame_left_top, text="年龄:", font=('Verdana', 15))
        self.right_top_gender_entry = Entry(self.frame_left_top, textvariable=self.var_age,
                                            font=('Verdana', 15))
        self.right_top_gender_label.grid(row=4, column=0)  # 位置设置
        self.right_top_gender_entry.grid(row=4, column=1)
        # 成绩
        self.right_top_score_label = Label(self.frame_left_top, text="成绩:", font=('Verdana', 15))
        self.right_top_score_entry = Entry(self.frame_left_top, textvariable=self.var_score,
                                            font=('Verdana', 15))
        self.right_top_score_label.grid(row=5, column=0)  # 位置设置
        self.right_top_score_entry.grid(row=5, column=1)

        # 定义右上方区域
        self.right_top_title = Label(self.frame_right_top, text="操作:", font=('Verdana', 10))

        self.tree.bind('<Button-1>', self.click)  # 左键获取位置
        self.right_top_button1 = ttk.Button(self.frame_right_top, text='新建学生信息', width=20, command=self.new_row)
        self.right_top_button2 = ttk.Button(self.frame_right_top, text='更新选中学生信息', width=20,
                                            command=self.updata_row)
        self.right_top_button3 = ttk.Button(self.frame_right_top, text='删除选中学生信息', width=20,
                                            command=self.del_row)
        self.right_top_button4 = ttk.Button(self.frame_right_top, text='导出为Excel文件', width=20,command=self.ex_row)

        # 位置设置
        self.right_top_title.grid(row=1, column=0, pady=5)
        self.right_top_button1.grid(row=2, column=0, padx=20, pady=5)
        self.right_top_button2.grid(row=3, column=0, padx=20, pady=5)
        self.right_top_button3.grid(row=4, column=0, padx=20, pady=5)
        self.right_top_button4.grid(row=5, column=0, padx=20, pady=5)

        # 整体区域定位
        self.frame_left_top.grid(row=0, column=0, padx=2, pady=5)
        self.frame_right_top.grid(row=0, column=1, padx=30, pady=30)
        self.frame_center.grid(row=1, column=0, columnspan=2, padx=4, pady=5)
        self.frame_bottom.grid(row=2, column=0, columnspan=2)

        self.frame_left_top.grid_propagate(0)
        self.frame_right_top.grid_propagate(0)
        self.frame_center.grid_propagate(0)
        self.frame_bottom.grid_propagate(0)

        self.frame_left_top.tkraise()  # 开始显示主菜单
        self.frame_right_top.tkraise()  # 开始显示主菜单
        self.frame_center.tkraise()  # 开始显示主菜单
        self.frame_bottom.tkraise()  # 开始显示主菜单

        self.window.protocol("WM_DELETE_WINDOW", self.back)  # 捕捉右上角关闭点击

    def back(self):
        StartPage(self.window)  # 显示主窗口 销毁本窗口

    #点击事件
    def click(self, event):
        self.col = self.tree.identify_column(event.x)  # 列
        self.row = self.tree.identify_row(event.y)  # 行

        print(self.col)
        print(self.row)
        self.row_info = self.tree.item(self.row, "values")
        self.var_id.set(self.row_info[0])
        self.var_name.set(self.row_info[1])
        self.var_gender.set(self.row_info[2])
        self.var_age.set(self.row_info[3])
        self.var_score.set(self.row_info[4])
        self.right_top_id_entry = Entry(self.frame_left_top, state='disabled', textvariable=self.var_id,
                                        font=('Verdana', 15))

        print('')

    #排序
    def tree_sort_column(self, tv, col, reverse):  # Treeview、列名、排列方式
        l = [(tv.set(k, col), k) for k in tv.get_children('')]
        l.sort(reverse=reverse)  # 排序方式 对列表进行顺序排序
        # rearrange items in sorted positions
        for index, (val, k) in enumerate(l):  # 根据排序后索引移动
            tv.move(k, '', index)
        tv.heading(col, command=lambda: self.tree_sort_column(tv, col, not reverse))  # 重写标题,使之成为再点倒序的标题

    #新建学生信息
    def new_row(self):
        print('123')
        print(self.var_id.get())
        print(self.id)
        #判断学生是否存在
        if str(self.var_id.get()) in self.id:
            messagebox.showinfo('警告!', '该学生已存在!')
        else:
            #判空
            if self.var_id.get() != '' and self.var_name.get() != '' and self.var_gender.get() != '' and self.var_age.get() != '' and self.var_score.get() != '':
                # 打开数据库连接
                db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')
                cursor = db.cursor()  # 使用cursor()方法获取操作游标
                sql = "INSERT INTO student_k(id, name, gender, age, score) \
				       VALUES ('%s', '%s', '%s', '%s', '%s')" % \
                      (self.var_id.get(), self.var_name.get(), self.var_gender.get(), self.var_age.get(), self.var_score.get())  # SQL 插入语句
                #sql插入并设置初始密码
                sqls = "INSERT INTO `stu_login_k` VALUES ('%s', '123456')" % (self.var_id.get())
                try:
                    cursor.execute(sql)  # 执行sql语句
                    cursor.execute(sqls)
                    db.commit()  # 提交到数据库执行
                except:
                    db.rollback()  # 发生错误时回滚
                    messagebox.showinfo('警告!', '数据库连接失败!')
                db.close()  # 关闭数据库连接

                self.id.append(self.var_id.get())
                self.name.append(self.var_name.get())
                self.gender.append(self.var_gender.get())
                self.age.append(self.var_age.get())
                self.score.append(self.var_score.get())
                self.tree.insert('', len(self.id) - 1, values=(
                    self.id[len(self.id) - 1], self.name[len(self.id) - 1], self.gender[len(self.id) - 1],
                    self.age[len(self.id) - 1], self.score[len(self.id) - 1]))
                self.tree.update()
                messagebox.showinfo('提示!', '插入成功!')
            else:
                messagebox.showinfo('警告!', '请填写学生数据')

    #修改学生信息
    def updata_row(self):
        res = messagebox.askyesnocancel('警告!', '是否更新所填数据?')
        if res == True:
            if self.var_id.get() == self.row_info[0]:  # 如果所填学号 与 所选学号一致
                # 打开数据库连接
                db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')
                cursor = db.cursor()  # 使用cursor()方法获取操作游标
                sql_update = "UPDATE student_k SET name = '%s', gender = '%s', age = '%s', score = '%s' \
				 WHERE id = '%s'" % (
                    self.var_name.get(), self.var_gender.get(), self.var_age.get(), self.var_id.get(), self.var_score.get())  # SQL 插入语句
                try:
                    cursor.execute(sql_update)  # 执行sql语句
                    db.commit()  # 提交到数据库执行
                    messagebox.showinfo('提示!', '更新成功!')
                except:
                    db.rollback()  # 发生错误时回滚
                    messagebox.showinfo('警告!', '更新失败,数据库连接失败!')
                db.close()  # 关闭数据库连接

                id_index = self.id.index(self.row_info[0])
                self.name[id_index] = self.var_name.get()
                self.gender[id_index] = self.var_gender.get()
                self.age[id_index] = self.var_age.get()
                self.score[id_index] = self.var_score.get()

                self.tree.item(self.tree.selection()[0], values=(
                    self.var_id.get(), self.var_name.get(), self.var_gender.get(),
                    self.var_age.get(), self.var_score.get()))  # 修改对于行信息
            else:
                messagebox.showinfo('警告!', '不能修改学生学号!')

    #删除学生信息
    def del_row(self):
        res = messagebox.askyesnocancel('警告!', '是否删除所选数据?')
        if res == True:
            print(self.row_info[0])  # 鼠标选中的学号
            print(self.tree.selection()[0])  # 行号
            print(self.tree.get_children())  # 所有行
            # 打开数据库连接
            db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')
            cursor = db.cursor()  # 使用cursor()方法获取操作游标
            sql_delete = "DELETE FROM student_k WHERE id = '%s'" % (self.row_info[0])  # SQL 插入语句
            sql_deletes = "DELETE  FROM stu_login_k WHERE stu_id = '%s'" % (self.row_info[0])  # SQL 插入语句
            try:
                cursor.execute(sql_delete)  # 执行sql语句
                cursor.execute(sql_deletes)
                db.commit()  # 提交到数据库执行
                messagebox.showinfo('提示!', '删除成功!')
            except:
                db.rollback()  # 发生错误时回滚
                messagebox.showinfo('警告!', '删除失败,数据库连接失败!')
            db.close()  # 关闭数据库连接

            id_index = self.id.index(self.row_info[0])
            print(id_index)
            del self.id[id_index]
            del self.name[id_index]
            del self.gender[id_index]
            del self.age[id_index]
            del self.score[id_index]
            print(self.id)
            self.tree.delete(self.tree.selection()[0])  # 删除所选行
            print(self.tree.get_children())

    #学生表导出表格形式
    def ex_row(self):
        # 打开数据库连接
        db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "SELECT * FROM student_k"  # SQL 查询所有学生信息
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 重置游标的位置
            cursor.scroll(0, mode='absolute')
            # 搜取所有结果
            results = cursor.fetchall()

            # 获取MYSQL里面的数据字段名称
            fields = cursor.description
            workbook = xlwt.Workbook()
            sheet = workbook.add_sheet('table_message', cell_overwrite_ok=True)

            # 写上字段信息
            for field in range(0, len(fields)):
                sheet.write(0, field, fields[field][0])

            # 获取并写入数据段信息
            row = 1
            col = 0
            for row in range(1, len(results) + 1):
                for col in range(0, len(fields)):
                    sheet.write(row, col, u'%s' % results[row - 1][col])

            workbook.save(r'D:/readout1.xlsx')
            print("导出excel文件成功!")
        except:
            print("Error: unable to fetch data")
            messagebox.showinfo('警告!', '数据库连接失败!')
        db.close()  # 关闭数据库连接


# 学生查看信息界面
class StudentView:
    def __init__(self, parent_window, student_id):
        parent_window.destroy()  # 销毁主界面

        self.window = tk.Tk()  # 初始框的声明
        self.window.title('学生信息')
        self.window.geometry('300x480')  # 这里的乘是小x
        # 防止用户调整尺寸
        self.window.resizable(0, 0)

        label = tk.Label(self.window, text='学生信息查看', bg='silver', font=('Verdana', 20), width=30, height=2)
        label.pack(pady=20)

        self.id = '学号:' + ''
        self.name = '姓名:' + ''
        self.gender = '性别:' + ''
        self.age = '年龄:' + ''
        self.score = '成绩:' + ''

        # 打开数据库连接
        db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "SELECT * FROM student_k WHERE id = '%s'" % (student_id)  # SQL 查询语句
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 获取所有记录列表
            results = cursor.fetchall()
            for row in results:
                self.id = '学号:' + row[0]
                self.name = '姓名:' + row[1]
                self.gender = '性别:' + row[2]
                self.age = '年龄:' + row[3]
                self.score = '成绩:' + row[4]
        except:
            print("Error: unable to fetch data")
        db.close()  # 关闭数据库连接

        # 数据库获取到数据显示在界面上
        Label(self.window, text=self.id, font=('Verdana', 12)).pack(pady=5)
        Label(self.window, text=self.name, font=('Verdana', 12)).pack(pady=5)
        Label(self.window, text=self.gender, font=('Verdana', 12)).pack(pady=5)
        Label(self.window, text=self.age, font=('Verdana', 12)).pack(pady=5)
        Label(self.window, text=self.score, font=('Verdana', 12)).pack(pady=5)

        Button(self.window, text="修改密码", width=8, font=tkFont.Font(size=16),
               command=lambda: Changekey(self.window)).pack(pady=25)

        Button(self.window, text="返回首页", width=8, font=tkFont.Font(size=16), command=self.back).pack(pady=25)

        self.window.protocol("WM_DELETE_WINDOW", self.back)  # 捕捉右上角关闭点击
        self.window.mainloop()  # 进入消息循环

    def back(self):
        StartPage(self.window)  # 显示主窗口 销毁本窗口


# 学生修改密码
class Changekey:
    def __init__(self, parent_window):
        parent_window.destroy()  # 销毁主界面

        self.window = tk.Tk()  # 初始框的声明
        self.window.title('学生账号修改页面')
        self.window.geometry('300x550')  # 这里的乘是小x
        # 防止用户调整尺寸
        self.window.resizable(0, 0)

        label = tk.Label(self.window, text='修改学生密码', bg='green', font=('Verdana', 20), width=30, height=2)
        label.pack()

        Label(self.window, text='学号:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_id = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')
        self.admin_id.pack()

        Label(self.window, text='旧密码:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_key = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory', show='*')
        self.admin_key.pack()

        Label(self.window, text='新密码:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_pass = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory', show='*')
        self.admin_pass.pack()

        Button(self.window, text="确定修改", width=8, font=tkFont.Font(size=12), command=self.login).pack(pady=40)
        Button(self.window, text="返回首页", width=8, font=tkFont.Font(size=12), command=self.back).pack()

    def login(self):
        print(str(self.admin_id.get()))
        print(str(self.admin_key.get()))
        stu_pass = None
        # 数据库操作 查询管理员表
        db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')  # 打开数据库连接
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "SELECT * FROM stu_login_k WHERE stu_id = '%s'" % (self.admin_id.get())  # SQL 查询语句
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 获取所有记录列表
            results = cursor.fetchall()
            for row in results:
                stu_id = row[0]
                stu_pass = row[1]
                # 打印结果
                print("stu_id=%s,stu_pass=%s" % (stu_id, stu_pass))
        except:
            print("Error: unable to fecth data")
            messagebox.showinfo('警告!', '用户名或密码不正确!')
        db.close()  # 关闭数据库连接

        print("正在修改")
        print("旧密码", self.admin_key.get())
        print("新密码", stu_pass)

        if self.admin_key.get() == stu_pass:
            self.chage()
        else:
            messagebox.showinfo('警告!', '用户名或密码不正确!')

    def chage(self):
        print(str(self.admin_id.get()))
        print(str(self.admin_key.get()))
        print(str(self.admin_pass.get()))
        db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "UPDATE stu_login_k SET stu_pass = '%s' WHERE stu_id = '%s'" % (
            self.admin_pass.get(), self.admin_id.get())
        try:
            cursor.execute(sql)  # 执行sql语句
            db.commit()  # 提交到数据库执行
            messagebox.showinfo('提示!', '更新成功!')
        except:
            db.rollback()  # 发生错误时回滚
            messagebox.showinfo('警告!', '更新失败,数据库连接失败!')
        db.close()  # 关闭数据库连接

    def back(self):
        StartPage(self.window)  # 显示主窗口 销毁本窗口


# 版本声明
class AboutPage:
    def __init__(self, parent_window):
        parent_window.destroy()  # 销毁主界面

        self.window = tk.Tk()  # 初始框的声明

        self.window.title('账号系统')
        self.window.geometry('300x420')
        # 防止用户调整尺寸
        self.window.resizable(0, 0)

        label = tk.Label(self.window, text='账号系统', bg='cyan', font=('Verdana', 20), width=30, height=2)
        label.pack()

        Label(self.window, text='学生账号为学号', font=('Verdana', 18)).pack(pady=5)
        Label(self.window, text='初始密码为123456', font=('Verdana', 18)).pack(pady=5)
        Label(self.window, text='版本:1.0.3', font=('Verdana', 16)).pack(pady=5)

        Button(self.window, text="修改密码", width=10, font=tkFont.Font(size=16),
               command=lambda: Changekey(self.window)).pack(pady=15)
        Button(self.window, text="管理员修改", width=10, font=tkFont.Font(size=16),
               command=lambda: Adminlogin(self.window)).pack(pady=15)
        Button(self.window, text="返回首页", width=10, font=tkFont.Font(size=16), command=self.back).pack(pady=15)

        self.window.protocol("WM_DELETE_WINDOW", self.back)  # 捕捉右上角关闭点击
        self.window.mainloop()  # 进入消息循环

    def back(self):
        StartPage(self.window)  # 显示主窗口 销毁本窗口


# 管理员登陆
class Adminlogin:
    def __init__(self, parent_window):
        parent_window.destroy()  # 销毁主界面

        self.window = tk.Tk()  # 初始框的声明
        self.window.title('请先登录任意管理员账号')
        self.window.geometry('300x500')  # 这里的乘是小x
        # 防止用户调整尺寸
        self.window.resizable(0, 0)

        label = tk.Label(self.window, text='管理员登陆', bg='green', font=('Verdana', 20), width=30, height=2)
        label.pack()

        Label(self.window, text='管理员账号:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_username = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')
        self.admin_username.pack()

        Label(self.window, text='管理员密码:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_pass = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory', show='*')
        self.admin_pass.pack()

        Button(self.window, text="修改密码", width=8, font=tkFont.Font(size=12), command=self.login_change).pack(pady=25)
        Button(self.window, text="创建账号", width=8, font=tkFont.Font(size=12), command=self.login_create).pack(pady=25)
        Button(self.window, text="返回首页", width=8, font=tkFont.Font(size=12), command=self.back).pack(pady=25)

        self.window.protocol("WM_DELETE_WINDOW", self.back)  # 捕捉右上角关闭点击
        self.window.mainloop()  # 进入消息循环

    # 新增管理员
    def login_create(self):
        print(str(self.admin_username.get()))
        print(str(self.admin_pass.get()))
        admin_pass = None

        # 数据库操作 查询管理员表
        db = pymysql.connect(host='localhost', port=3306, db='student',user='root', password='123456')  # 打开数据库连接
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "SELECT * FROM admin_login_k WHERE admin_id = '%s'" % (self.admin_username.get())  # SQL 查询语句
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 获取所有记录列表
            results = cursor.fetchall()
            for row in results:
                admin_id = row[0]
                admin_pass = row[1]
                # 打印结果
                print("admin_id=%s,admin_pass=%s" % (admin_id, admin_pass))
        except:
            print("Error: unable to fecth data")
            messagebox.showinfo('警告!', '用户名或密码不正确!')
        db.close()  # 关闭数据库连接

        print("正在登陆管理员创建界面")
        print("self", self.admin_pass)
        print("local", admin_pass)

        if self.admin_pass.get() == admin_pass:
            CreateAdminPage(self.window)
        else:
            messagebox.showinfo('警告!', '用户名或密码不正确!')

    # 管理员修改密码
    def login_change(self):
        print(str(self.admin_username.get()))
        print(str(self.admin_pass.get()))
        admin_pass = None

        # 数据库操作 查询管理员表
        db = pymysql.connect(host='localhost', port=3306, db='student',user='root', password='123456')  # 打开数据库连接
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "SELECT * FROM admin_login_k WHERE admin_id = '%s'" % (self.admin_username.get())  # SQL 查询语句
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 获取所有记录列表
            results = cursor.fetchall()
            for row in results:
                admin_id = row[0]
                admin_pass = row[1]
                # 打印结果
                print("admin_id=%s,admin_pass=%s" % (admin_id, admin_pass))
        except:
            print("Error: unable to fecth data")
            messagebox.showinfo('警告!', '用户名或密码不正确!')
        db.close()  # 关闭数据库连接

        print("正在登陆管理员创建界面")
        print("self", self.admin_pass)
        print("local", admin_pass)


        if self.admin_pass.get() == admin_pass:
            AdminChange(self.window)
        else:
            messagebox.showinfo('警告!', '用户名或密码不正确!')

    # 销毁窗口
    def back(self):
        StartPage(self.window)  # 显示主窗口 销毁本窗口


# 创建管理员
class CreateAdminPage:
    def __init__(self, parent_window):
        parent_window.destroy()  # 销毁主界面

        self.window = tk.Tk()  # 初始框的声明
        self.window.title('管理员账号注册')
        self.window.geometry('300x450')  # 这里的乘是小x
        # 防止用户调整尺寸
        self.window.resizable(0, 0)

        Label(self.window, text='管理员用户名:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_id = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')
        self.admin_id.pack()

        Label(self.window, text='设置密码:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_pass = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory', show='*')
        self.admin_pass.pack()

        Button(self.window, text="创建用户", width=8, font=tkFont.Font(size=12), command=self.find).pack(pady=40)
        Button(self.window, text="返回首页", width=8, font=tkFont.Font(size=12), command=self.back).pack()

    def back(self):
        StartPage(self.window)  # 显示主窗口 销毁本窗口

    def find(self):
        print(str(self.admin_id.get()))
        print(str(self.admin_pass.get()))

        # 数据库操作 查询管理员表
        db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456') # 打开数据库连接
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "SELECT admin_id FROM admin_login_k WHERE admin_id = '%s'" % \
              (self.admin_id.get())  # SQL 查询语句
        try:
            # 执行SQL语句
            cursor.execute(sql)
            # 获取所有记录列表
            results = cursor.fetchall()
            print(results)
            if self.admin_id.get in results:
                print("Error: name already exists!")
                messagebox.showinfo('警告!', '用户名已存在!')
            else:
                self.change()

        except:
            print("Error: unable to fecth data")
            messagebox.showinfo('警告!', '用户名或密码不正确!')

    #添加管理员
    def change(self):
        print(str(self.admin_id.get()))
        print(str(self.admin_pass.get()))

        # 数据库操作 查询管理员表
        db = pymysql.connect(host='localhost', port=3306, db='student',user='root', password='123456') # 打开数据库连接
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "INSERT INTO admin_login_k(admin_id, admin_pass) VALUES ('%s', '%s')" % \
              (self.admin_id.get(), self.admin_pass.get())  # SQL 查询语句
        try:
            cursor.execute(sql)  # 执行sql语句
            db.commit()  # 提交到数据库执行
        except:
            db.rollback()  # 发生错误时回滚
            messagebox.showinfo('警告!', '数据库连接失败!')

        db.close()  # 关闭数据库连接

        messagebox.showinfo('提示', '创建成功')


# 管理员密码修改
class AdminChange:
    def __init__(self, parent_window):
        parent_window.destroy()  # 销毁主界面

        self.window = tk.Tk()  # 初始框的声明
        self.window.title('管理员密码修改')
        self.window.geometry('300x450')  # 这里的乘是小x
        # 防止用户调整尺寸
        self.window.resizable(0, 0)

        Label(self.window, text='管理员用户名:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_id = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')
        self.admin_id.pack()

        Label(self.window, text='设置密码:', font=tkFont.Font(size=14)).pack(pady=25)
        self.admin_pass = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory', show='*')
        self.admin_pass.pack()

        Button(self.window, text="确定修改", width=8, font=tkFont.Font(size=12), command=self.chage).pack(pady=40)
        Button(self.window, text="返回首页", width=8, font=tkFont.Font(size=12), command=self.back).pack()

    def chage(self):
        print(str(self.admin_id.get()))
        print(str(self.admin_pass.get()))

        # 数据库操作 查询管理员表
        db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')  # 打开数据库连接
        cursor = db.cursor()  # 使用cursor()方法获取操作游标
        sql = "UPDATE admin_login_k SET admin_pass = '%s' WHERE admin_id = '%s'" % \
              (self.admin_pass.get(), self.admin_id.get())  # SQL 查询语句
        try:
            cursor.execute(sql)  # 执行sql语句
            db.commit()  # 提交到数据库执行
            messagebox.showinfo('提示!', '更新成功!')
        except:
            db.rollback()  # 发生错误时回滚
            messagebox.showinfo('警告!', '更新失败,数据库连接失败!')
        db.close()  # 关闭数据库连接

    def back(self):
        StartPage(self.window)  # 显示主窗口 销毁本窗口


# 创建数据库 实例化Application
if __name__ == '__main__':
    try:
        # 打开数据库连接 连接测试
        db = pymysql.connect(host='localhost', port=3306, db='student', user='root', password='123456')
        # 使用cursor()方法获取操作游标
        cursor = db.cursor()
        # 如果数据表不存在则创建表 若存在则跳过
        # 设置主键唯一
        sql = """CREATE TABLE IF NOT EXISTS student_k(
				id char(20) NOT NULL,
				name char(20) default NULL,
				gender char(5) default NULL,  
				age char(5) default NULL,
				PRIMARY KEY (id)

				) ENGINE = InnoDB 
				DEFAULT	CHARSET = utf8
				"""
        cursor.execute(sql)
        # 如果数据表不存在则创建表 若存在则跳过
        sql = """CREATE TABLE IF NOT EXISTS admin_login_k(
						admin_id char(20) NOT NULL,
						admin_pass char(20) default NULL,
						PRIMARY KEY (admin_id)
						) ENGINE = InnoDB 
						DEFAULT	CHARSET = utf8
						"""
        cursor.execute(sql)
        # 如果数据表不存在则创建表 若存在则跳过
        sql = """CREATE TABLE IF NOT EXISTS stu_login_k(
						stu_id char(20) NOT NULL,
						stu_pass char(20) default NULL,
						PRIMARY KEY (stu_id)
						) ENGINE = InnoDB 
						DEFAULT	CHARSET = utf8
						"""
        cursor.execute(sql)

        # 关闭数据库连接
        db.close()

        # 实例化Application
        window = tk.Tk() # 创建窗口
        StartPage(window) # 调用StartPage方法

    except:
        messagebox.showinfo('错误!', '连接数据库失败!')

数据库文件

SET FOREIGN_KEY_CHECKS=0;
 
-- ----------------------------
-- Table structure for `admin_login_k`
-- ----------------------------
DROP TABLE IF EXISTS `admin_login_k`;
CREATE TABLE `admin_login_k` (
  `admin_id` char(20) NOT NULL,
  `admin_pass` char(20) DEFAULT NULL,
  PRIMARY KEY (`admin_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Records of admin_login_k
-- ----------------------------
INSERT INTO `admin_login_k` VALUES ('admin', 'admin');
 
-- ----------------------------
-- Table structure for `student_k`
-- ----------------------------
DROP TABLE IF EXISTS `student_k`;
CREATE TABLE `student_k` (
  `id` char(20) NOT NULL,
  `name` char(20) DEFAULT NULL,
  `gender` char(5) DEFAULT NULL,
  `age` char(5) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Records of student_k
-- ----------------------------
INSERT INTO `student_k` VALUES ('209114122', '徐志强', '男', '21');
INSERT INTO `student_k` VALUES ('206546845', '张浩', '男', '21');
INSERT INTO `student_k` VALUES ('182085215', '汤姆', '男', '23');
INSERT INTO `student_k` VALUES ('182085211', '杰瑞', '男', '21');
INSERT INTO `student_k` VALUES ('182085212', '鲍勃', '男', '24');
INSERT INTO `student_k` VALUES ('182011011', '派大星', '男', '23');
INSERT INTO `student_k` VALUES ('209084163', '珊迪', '女', '29');
INSERT INTO `student_k` VALUES ('209045599', '章鱼哥', '男', '38');
INSERT INTO `student_k` VALUES ('209055599', '蟹阿金', '男', '42');
-- ----------------------------
-- Table structure for `stu_login_k`
-- ----------------------------
DROP TABLE IF EXISTS `stu_login_k`;
CREATE TABLE `stu_login_k` (
  `stu_id` char(20) NOT NULL,
  `stu_pass` char(20) DEFAULT NULL,
  PRIMARY KEY (`stu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Records of stu_login_k
-- ----------------------------
INSERT INTO `stu_login_k` VALUES ('209114122', '123456');
INSERT INTO `stu_login_k` VALUES ('206546845', '123456');
INSERT INTO `stu_login_k` VALUES ('182085215', '123456');
INSERT INTO `stu_login_k` VALUES ('182085211', '123456');
INSERT INTO `stu_login_k` VALUES ('182085212', '123456');
INSERT INTO `stu_login_k` VALUES ('182011011', '123456');
INSERT INTO `stu_login_k` VALUES ('209084163', '123456');
INSERT INTO `stu_login_k` VALUES ('209045599', '123456');
INSERT INTO `stu_login_k` VALUES ('209055599', '123456');

 
-- ----------------------------
-- Table structure for `t_course`
-- ----------------------------
DROP TABLE IF EXISTS `t_course`;
CREATE TABLE `t_course` (
  `SNO` char(255) NOT NULL,
  `COURSE` char(255) DEFAULT NULL,
  `CREDIT` char(255) DEFAULT NULL,
  `GRADE` char(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Records of t_course
-- ----------------------------
INSERT INTO `t_course` VALUES ('08300205', '程序设计', '4', '88');
INSERT INTO `t_course` VALUES ('08300205', '数据库', '2.5', '90');
INSERT INTO `t_course` VALUES ('08300205', 'python', '5', '92');
INSERT INTO `t_course` VALUES ('08080929', '数据库', '2.5', '85');
INSERT INTO `t_course` VALUES ('09350124', '数据库', '2.5', '92');
INSERT INTO `t_course` VALUES ('09620233', '数据库', '2.5', '80');
INSERT INTO `t_course` VALUES ('09300218', '数据库', '2.5', '78');
INSERT INTO `t_course` VALUES ('09010122', '数据库', '2.5', '87');
INSERT INTO `t_course` VALUES ('08080929', '程序设计', '4', '86');
INSERT INTO `t_course` VALUES ('09010122', '程序设计', '4', '80');
INSERT INTO `t_course` VALUES ('08300516', '程序设计', '4', '76');
 
-- ----------------------------
-- Table structure for `t_st`
-- ----------------------------
DROP TABLE IF EXISTS `t_st`;
CREATE TABLE `t_st` (
  `SNO` char(11) NOT NULL,
  `SNAME` char(255) DEFAULT NULL,
  `SSEX` char(255) DEFAULT NULL,
  `AGE` char(255) DEFAULT NULL,
  `DEPT` char(255) DEFAULT NULL,
  PRIMARY KEY (`SNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Records of t_st
-- ----------------------------
INSERT INTO `t_st` VALUES ('209044483', '王晨阳', '男', '20', '计204');

项目总结与体会

开发本项目时,我具有开发类似项目的开发经验,但利用python进行开发,对于我来说是比较具有挑战性的。并且开发本系统的时间较短,开发的反复性比较多,对客户的需求理解不是很透彻,综合以上,我对于本次项目的开发效率不是很高,相反有相当一定时间的浪费。然而经过我系统地梳理,并根据老师的需求,先从数据库开始下手,分析每个功能所需要的数据,最后完成设计数据库。接着我开始制定开发方向,最后我选择的是thinter库作为主要开发库实现。tkinter是使用 python 进行窗口视窗设计的模块。tkinter是python自带的,可以编辑的GUI界面,我之所以选择Tkinter,一是最为简单,二是自带库,不需下载安装,随时使用。还有我主要使用了Treeview这个部件,它的功能非常强大。首先它是树形图和列表相结合,在第一列是它的树状结构,后面几列的是列表结构。Treeview常用于展示带层级的数据,每一个数据项(data item)可以有一个文本、图片和多列数据值(colum values)。数据列的显示排序可以通过diaplaycolumns来设定,treeview还可以显示数据列的头部。每个数据项(item)有一个唯一的名字(name)和ID,如果创建item时未指定ID会自动生成。Treeview支持横向和竖向的滚动条,可通过xscrollcommand、yscrollcom.mand和Treeview.xview()、Treeview.yview()设置和控制。最后就是到了测试环节,我对每个功能测试了两三遍,为的就是降低bug的出现率。通过本次项目的开发,让我对python开发又有了一次全新的认识,我后面还会继续深入学习python,体会python带来的学习乐趣,正所谓“人生苦短,我用python!”。

  • 2
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值