登录系统:时间显示、管理员登录与注册、作者信息展示、退出程序
功能系统:退出程序、录入学生、输出学生、修改学生、另存学生、学生成绩排序、打印成绩曲线图
课题总体结构:
类的功能定义 | |
分 类 | 内 容 |
Database | 功能的具体实现 |
Project | 数据的输入和功能目录 |
AboutPage | 作者信息页面 |
StartPage | 登录主页面 |
AdminPage | 管理员登录页面 |
Admin | 注册页面 |
详细实现:
登录与注册(采用了Tkinter界面,使用按钮)
窗口:StartPage
import pymysql
from Stu_manage_system.Project import Student
import tkinter as tk
import tkinter.font as tkFont
from tkinter import * # 图形界面库
import tkinter.messagebox as messagebox
import time
stu = Student()
class AboutPage(object):
def __init__(self, parent_window):
parent_window.update()
parent_window.destroy() # 销毁主界面
self.window = tk.Tk() # 初始框的声明
self.window.title('关于')
self.window.geometry('700x600+70+50') # 这里的乘是小x
label = tk.Label(self.window, text='用户信息管理系统', bg='SkyBlue', font=('楷体', 20), width=70, height=2)
label.pack()
Label(self.window, text='作者:gwqqqq', font=('Verdana', 18)).pack(pady=30)
Label(self.window, text='2021/6/11 制作', font=('Verdana', 18)).pack(pady=5)
Button(self.window, text="返回首页", width=8, font=tkFont.Font(size=12), command=self.back).pack(pady=150)
self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击
def back(self):
StartPage(self.window) # 显示主窗口 销毁本窗口
class StartPage:
def __init__(self, parent_windeow):
parent_windeow.update()
parent_windeow.destroy() # 销毁子届面
self.window = tk.Tk()
self.window.title('信息管理系统')
self.window.geometry('700x600+70+50')
def getTime():
timeStr = time.strftime('%H:%M:%S')
Rtime.configure(text=timeStr)
self.window.after(1000, getTime)
Rtime = Label(self.window, text='')
Rtime.pack(pady=25)
getTime()
label = Label(self.window, text="学生信息管理系统", font={"楷体", 40})
label.pack(pady=100) # pady=100 界面的长度
# 按钮
Button(self.window, text="管理员登陆", font=tkFont.Font(size=16), command=lambda: AdminPage(self.window), width=47,
height=2, fg='white', bg='gray').place(x=100, y=300)
Button(self.window, text="作者信息", font=tkFont.Font(size=16), command=lambda: AboutPage(self.window), width=20,
height=2, fg='white', bg='gray').place(x=100, y=400)
Button(self.window, text='退出系统', font=tkFont.Font(size=16), command=self.window.destroy, width=20, height=2,
fg='white', bg='gray').place(x=400, y=400)
self.window.mainloop() # 主页面循环
class AdminPage:
def __init__(self, parent_window):
parent_window.update()
parent_window.destroy() # 销毁主页面
self.window = tk.Tk() # 初始框的声明
self.window.title('管理员登录页面')
self.window.geometry('700x600+70+50')
# 菜单
menubar = Menu(self.window)
menubar.add_cascade(label="管理员注册", command=lambda: Admin(self.window))
self.window.config(menu=menubar)
self.window['menu'] = menubar
self.window.protocol('WM_DELETE_WINDOW', self.back) # 捕捉右上角关闭点击
label = tk.Label(self.window, text='管理员登陆', bg='SkyBlue', font=('楷体', 20), width=70, height=2)
label.pack()
Label(self.window, text='管理员账号:', font=tkFont.Font(size=14)).pack(pady=25)
self.guanli_username = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')
self.guanli_username.pack()
Label(self.window, text='管理员密码:', font=tkFont.Font(size=14)).pack(pady=25)
self.guanli_pass = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory', show='*')
self.guanli_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):
guanli_pass = None
# 数据库操作 查询管理员表
db1 = pymysql.connect(host='localhost', user='root', password='123456', database='py_stu')
cursor1 = db1.cursor() # 调用cursor()方法获取操作游标
sql = "SELECT * FROM guanli WHERE guanli_id = '%s'" % (self.guanli_username.get()) # SQL 查询语句
try:
# 执行sql语句
cursor1.execute(sql)
# 获取所有记录列表
results = cursor1.fetchall()
for row in results:
guanli_id = row[0]
guanli_pass = row[1]
# 打印结果
except:
print("Error: unable to fecth data")
messagebox.showinfo('警告!', '用户名或密码不正确!')
db1.close() # 关闭数据库 连接
if self.guanli_pass.get() == guanli_pass:
self.window.destroy()
stu.run()
else:
messagebox.showinfo('警告!', '用户名或密码不正确!')
def back(self):
StartPage(self.window) # 显示主窗口 销毁本窗口
class Admin:
def __init__(self, parent_window):
parent_window.update()
parent_window.destroy() # 销毁主界面
self.window = tk.Tk() # 初始框的声明
self.window.title('管理员注册页面')
self.window.geometry('700x600+70+50')
label = tk.Label(self.window, text='管理员注册', bg='SkyBlue', font=('楷体', 20), width=70, height=2)
label.pack()
Label(self.window, text='注册账号:', font=tkFont.Font(size=14)).pack(pady=25)
self.guanli_username = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')
self.guanli_username.pack()
Label(self.window, text='注册密码:', font=tkFont.Font(size=14)).pack(pady=25)
self.guanli_pass = tk.Entry(self.window, width=30, font=tkFont.Font(size=14), bg='Ivory')
self.guanli_pass.pack()
Button(self.window, text="确定", width=8, font=tkFont.Font(size=12), command=self.login1).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) # 捕捉右上角关闭点击
def login1(self):
db = pymysql.connect(host='localhost', user='root', password='123456', database='py_stu')
cursor = db.cursor() # 使用cursor()方法获取操作游标
sql = "INSERT INTO guanli(guanli_id,guanli_pass) VALUES ('%s', '%s')" % (
self.guanli_username.get(), self.guanli_pass.get())
if self.guanli_username.get() != '' and self.guanli_pass.get() != '':
try:
cursor.execute(sql) # 执行sql语句
db.commit() # 提交到数据库执行
messagebox.showinfo('欢迎', '注册成功,欢迎管理员!')
except:
db.rollback() # 发生错误时回滚
messagebox.showinfo('警告!', '账号已被注册!')
else:
messagebox.showinfo('警告!', '不能为空!')
db.close() # 关闭数据库连接
def back(self):
AdminPage(self.window)
if __name__ == '__main__':
window = tk.Tk()
StartPage(window)
控制:Project.py
from Stu_manage_system.Database import Database
class Student(object):
# 定义用户名和密码
user = None
password = None
# 录入学生
def addstudent(self):
studentNumber = int(input("请输入录入的学生人数:"))
for i in range(studentNumber):
sno = input("请输入学号:")
if not Database.determinestudent(Database, self.user, self.password, sno):
sname = input("请输入姓名:")
sex = input("请输入性别:")
birthday = input("请输入生日:")
phone = input("请输入电话:")
dorm = input("请输入宿舍号:")
score = input("请输入成绩:")
Database.addstudent(Database, self.user, self.password, sno, sname, sex, birthday, phone, dorm, score)
print("加入学生成功!!!\n")
# 输出学生
def showstudent(self):
print("学生信息输出如下:")
Database.showstudent(Database, self.user, self.password)
# 删除学生
def deletestudent(self):
sno = input("请输入删除学生学号:")
Database.deletestudent(Database, self.user, self.password, sno)
# 查询学生
def selectstudent(self):
sno = input("请输入查询学生的学号")
Database.selectstudent(Database, self.user, self.password, sno)
# 修改学生
def changestudent(self):
sno = input("请输入修改学生的学号:")
if Database.selectstudent(Database, self.user, self.password, sno):
sname = input("请输入姓名:")
sex = input("请输入性别:")
birthday = input("请输入生日:")
phone = input("请输入电话:")
dorm = input("请输入宿舍号:")
score = input("请输入成绩:")
Database.updatestudent(Database, self.user, self.password, sno, sname, sex, birthday, phone, dorm, score)
# 学生成绩排序
def scorerank(self):
print("学生成绩输出如下:")
Database.scorerank(Database, self.user, self.password)
def datashow(self):
print("学生成绩曲线图已打印:")
Database.datashow(Database, self.user, self.password)
# 界面打印
@staticmethod
def printUI():
print("**************************")
print("** 输入:0 --退出程序-- **")
print("** 输入:1 --录入学生-- **")
print("** 输入:2 --输出学生-- **")
print("** 输入:3 --删除学生-- **")
print("** 输入:4 --查询学生-- **")
print("** 输入:5 --修改学生-- **")
print("** 输入:6 --另存学生-- **")
print("** 输出:7 --学生成绩排序-- **")
print("** 输出:8 --打印成绩曲线图-- **")
print("**************************")
# 登录界面
def ui(self):
print("***********************************")
print("** 欢迎使用学生信息管理系统 **")
print("** 加载中 **")
print("***********************************")
self.user = "root"
self.password = "123456"
# 保存程序
def data(self):
Database.savestudent(Database, self.user, self.password)
# 程序调用
def run(self):
while True:
Student.ui(Student)
if Database.condatabase(Database, self.user, self.password):
print("登录成功!!!")
self.printUI()
number = input("请输入执行的功能:")
# 无限循环
while True:
if int(number) == 1:
self.addstudent()
self.printUI()
number = input("请输入执行的功能:")
elif int(number) == 2:
self.showstudent()
self.printUI()
number = input("请输入执行的功能:")
elif int(number) == 3:
self.deletestudent()
self.printUI()
number = input("请输入执行的功能:")
elif int(number) == 4:
self.selectstudent()
self.printUI()
number = input("请输入执行的功能:")
elif int(number) == 5:
self.changestudent()
self.printUI()
number = input("请输入执行的功能:")
elif int(number) == 6:
self.data()
self.printUI()
number = input("请输入执行的功能:")
elif int(number) == 7:
self.scorerank()
self.printUI()
number = input("请输入执行的功能:")
elif int(number) == 8:
self.datashow()
self.printUI()
number = input("请输入执行的功能:")
elif int(number) == 0:
break
else:
print("您输入的序号不对!\n请重新输入!")
self.printUI()
number = input("请输入执行的功能:")
print("感谢使用!!!\n再见!!!")
exit()
elif self.user == "exit":
exit()
实现类:Database.py
import pymysql
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm # 字体管理器
class Database:
db = None
cursor = None
# 连接数据库
def condatabase(self, user, password):
# 打开数据库连接
try:
self.db = pymysql.connect(host='localhost', user="root", password="123456", database='py_stu')
# 使用 cursor() 方法创建一个游标对象 cursor
self.cursor = self.db.cursor()
return True
except:
return False
# 加入学生
def addstudent(self, user, password, sno, sname, sex, birthday, phone, dorm, score):
self.condatabase(self, user, password)
sql = "insert into py_stu value " \
"(%s,%s,%s,%s,%s,%s,%s)" % (
repr(sno), repr(sname), repr(sex), repr(birthday), repr(phone), repr(dorm), repr(score))
try:
# 使用 exercute() 方法执行SQL
self.cursor.execute(sql)
self.db.commit()
except:
self.db.rollback()
# 关闭数据库连接
self.db.close()
# 输出学生
def showstudent(self, user, password):
self.condatabase(self, user, password)
sql = "select * from py_stu"
try:
self.cursor.execute(sql)
student = self.cursor.fetchall()
for row in student:
print("学号:%s 姓名:%s 性别:%s 生日:%s 电话:%s 宿舍号:%s 成绩:%s" % (
row[0], row[1], row[2], row[3], row[4], row[5], row[6]))
except:
self.db.rollback()
self.db.close()
# 查询学生
def selectstudent(self, user, password, sno):
self.condatabase(self, user, password)
sql = "select * from py_stu where sno = %s" % repr(sno)
try:
self.cursor.execute(sql)
row = self.cursor.fetchone()
print(
"学号:%s 姓名:%s 性别:%s 生日:%s 电话:%s 宿舍号:%s 成绩:%s" % (row[0], row[1], row[2], row[3], row[4], row[5], row[6]))
return True
except:
self.db.rollback()
print("未查询到当前学生!!!")
return False
self.db.close()
# 删除学生
def deletestudent(self, user, password, sno):
self.condatabase(self, user, password)
sql = "delete from py_stu where sno = %s" % repr(sno)
try:
self.cursor.execute(sql)
self.db.commit()
print("删除成功!!!")
except:
self.db.rollback()
print("不存在当前学生")
self.db.close()
# 修改学生
def updatestudent(self, user, password, sno, sname, sex, birthday, phone, dorm, score):
self.condatabase(self, user, password)
sql = "update py_stu " \
"set sname = %s ," \
"sex = %s ," \
"birthday = %s ," \
"phone = %s ," \
"dorm = %s ," \
"score = %s" \
"where sno = %s" % \
(repr(sname), repr(sex), repr(birthday), repr(phone), repr(dorm), repr(score), repr(sno))
try:
self.cursor.execute(sql)
self.db.commit()
print("更新学生信息成功!!!")
except:
self.db.rollback()
print("更新学生信息失败!!!")
self.db.close()
# 另存学生信息
def savestudent(self, user, password):
# 以追加的形式添加
dataFile = open("D:\\text.txt", "a")
self.condatabase(self, user, password)
sql = "select * from py_stu"
try:
self.cursor.execute(sql)
student = self.cursor.fetchall()
for row in student:
dataFile.write(
"学号:" + row[0] + " 姓名:" + row[1] + " 性别:" + row[2] + " 生日" + row[3] + " 电话:" + row[
4] + " 宿舍号:" + row[5] + " 成绩:" + row[6] + "\n")
print("保存成功!!!")
except:
self.db.rollback()
print("保存失败!!!")
self.db.close()
dataFile.close()
# 判断学号重复
def determinestudent(self, user, password, sno):
self.condatabase(self, user, password)
sql = "select * from py_stu where sno = %s" % repr(sno)
try:
self.cursor.execute(sql)
row = self.cursor.fetchone()
if row is not None:
print("学号重复!!!\n重复学生为:")
print("学号:%s 姓名:%s 性别:%s 生日:%s 电话:%s 宿舍号:%s 成绩:%s"
% (row[0], row[1], row[2], row[3], row[4], row[5], row[6]))
return True
except:
self.db.rollback()
return False
self.db.close()
# 学生成绩排序
def scorerank(self, user, password):
self.condatabase(self, user, password)
sql = "select * from py_stu order by score"
try:
self.cursor.execute(sql)
student = self.cursor.fetchall()
for row in student:
print("学号:%s 姓名:%s 性别:%s 生日:%s 电话:%s 宿舍号:%s 成绩:%s" % (
row[0], row[1], row[2], row[3], row[4], row[5], row[6]))
except:
self.db.rollback()
self.db.close()
# 学生成绩曲线图
def datashow(self, user, password):
x_data = []
y_data = []
self.condatabase(self, user, password)
sql = "select sno, sname, score from py_stu "
try:
self.cursor.execute(sql)
student = self.cursor.fetchall()
for row in student:
print("学号:%s 姓名:%s 成绩:%s" % (
row[0], row[1], row[2]))
x_data.append(row[0])
y_data.append(int(row[2]))
plt.plot(x_data, y_data, color="red", linewidth="2.0")
# my_font = fm.FontProperties(fname="C:\Windows\Fonts\Consolas.TTF")
# plt.title("学生成绩曲线图", fontproperties=my_font) # 设置标题及字体
plt.show()
except:
self.db.rollback()
self.db.close()
- 运行及调试
登录注册实现(运用tkinter实现窗口化)
调试:
1、实现窗口转console的同时关闭窗口。
2、实现曲线图的绘制
- 课程设计小结
通过对python的学习,运用所学完成简单的学生管理系统。对于管理系统的运用Tkinter窗口化实现管理员的登录注册,同时建立数据库存储管理员的账号、密码。同时需要考虑到窗口如何转到任务栏,并且关闭窗口,设置窗口的返回,使用mianloop对主窗口的循环。在功能实现方面,采用if语句判断用户的选择,完成各个功能的实现。本实验还有部分不足。无法进行打包成exe。同时作者的想法并没有得到完美的实现,对于用户输入数据的限制不是特别完善。还有很多地方可以修改。仍需继续努力。
- 首先下载相应的库
- 根据要求建立响应的数据库和表
- 实现规格化输出
plt.rcParams['font.sans-serif'] = ['KaiTi']