xyz20020922 1 year ago
parent f2bec40ed4
commit 275f725927

@ -1,8 +1,8 @@
# 默认忽略的文件 # Default ignored files
/shelf/ /shelf/
/workspace.xml /workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files # Datasource local storage ignored files
/dataSources/ /dataSources/
/dataSources.local.xml /dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

@ -1,10 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4"> <module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$" />
<excludeFolder url="file://$MODULE_DIR$/.venv" /> <orderEntry type="jdk" jdkName="Python 3.12 (pythonProject)" jdkType="Python SDK" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="Black"> <component name="Black">
<option name="sdkName" value="Python 3.12 (pythonProject100)" /> <option name="sdkName" value="Python 3.12 (pythonProject)" />
</component> </component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (pythonProject100)" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (pythonProject)" project-jdk-type="Python SDK" />
</project> </project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/StudentInformationManagementSystem.iml" filepath="$PROJECT_DIR$/.idea/StudentInformationManagementSystem.iml" />
</modules>
</component>
</project>

@ -0,0 +1,28 @@
import pymysql
class MysqlConfig:
user = 'root' # MySQL用户名
password = '123456' # MySQL密码
db = None
cursor = None
@staticmethod
def create_mysql():
try:
db = pymysql.connect(host="localhost", user=MysqlConfig.user, password=MysqlConfig.password,
database=None) # 数据库链接,不指明具体的数据库
cursor = db.cursor() # 获得游标对象
sql_1 = "CREATE DATABASE IF NOT EXISTS python_test;" # 创建名为python_test的数据库
sql_2 = "CREATE TABLE IF NOT EXISTS t_student( sid bigint(20) PRIMARY KEY AUTO_INCREMENT ," \
" sno varchar(20) , sname varchar(20), " \
"sex varchar(20), age int, phone varchar(20), dormNo varchar(20)); "
sql_3 = "CREATE TABLE IF NOT EXISTS t_user( uid bigint(20) PRIMARY KEY AUTO_INCREMENT ," \
" user_name varchar(20) , user_password varchar(20),UNIQUE INDEX (user_name));"
cursor.execute(sql_1) # 执行语句
MysqlConfig.db = pymysql.connect(host="localhost", user=MysqlConfig.user, password=MysqlConfig.password,
database="python_test") # 数据库链接指定名为python_test的数据库
MysqlConfig.cursor = MysqlConfig.db.cursor() # 使用 cursor() 方法创建一个游标对象 cursor
MysqlConfig.cursor.execute(sql_2) # 执行语句
MysqlConfig.cursor.execute(sql_3)
except Exception as ex:
print("出现异常:%s" % ex)

@ -0,0 +1,27 @@
from dao.MysqlConfig import MysqlConfig
class StudentDao:
@staticmethod # 增删改的方法
def update_student(sql, *params):
try:
MysqlConfig.cursor.execute(sql, params)
except Exception as ex:
print("出现异常:%s" % ex)
MysqlConfig.db.rollback()
@staticmethod # 查询学生的方法
def query_student(sno):
sql = "SELECT * FROM t_student WHERE sno = %s" % repr(sno)
MysqlConfig.cursor.execute(sql) # 执行语句
MysqlConfig.db.commit() # 提交
return MysqlConfig.cursor.fetchone() # 返回查询到的结果
@staticmethod # 查询全部学生的方法
def query_all():
sql = 'SELECT * FROM t_student;'
MysqlConfig.cursor.execute(sql) # 执行语句
MysqlConfig.db.commit() # 提交
return MysqlConfig.cursor.fetchall() # 返回查询到的结果

@ -0,0 +1,21 @@
from dao.MysqlConfig import MysqlConfig
class UserDao:
@staticmethod # 增删改的方法
def update_user(sql, *params):
try:
MysqlConfig.cursor.execute(sql, params)
except Exception as ex:
print("出现异常:%s" % ex)
MysqlConfig.db.rollback()
@staticmethod # 查询用户的方法
def query_user(user_name):
sql = "SELECT * FROM t_user WHERE user_name = %s" % repr(user_name)
MysqlConfig.cursor.execute(sql) # 执行语句
MysqlConfig.db.commit() # 提交
return MysqlConfig.cursor.fetchone() # 返回查询到的结果

@ -0,0 +1,6 @@
from dao.MysqlConfig import MysqlConfig
from ui.StudentUI import *
if __name__ == '__main__':
MysqlConfig.create_mysql()
StudentUI.init_login()

@ -0,0 +1,95 @@
from tkinter import END, INSERT
from tkinter.messagebox import *
from dao.StudentDao import StudentDao
from utils.ExcelUtils import ExcelUtils
class StudentService:
@staticmethod
def add_student(list_entry):
sno = list_entry[0].get()
if sno == '':
showwarning(title="警告", message="学号不能为空!\n加入失败!")
return
result = StudentDao.query_student(sno) # 根据学号查询学生
if result is not None:
showwarning(title="警告", message="学号重复!\n加入失败!")
return
sql = "INSERT INTO t_student(sno,sname,sex,age,phone,dormNo) VALUES(%s,%s,%s,%s,%s,%s)"
StudentDao.update_student(sql, list_entry[0].get(), list_entry[1].get(), list_entry[2].get(),
list_entry[3].get(), list_entry[4].get(), list_entry[5].get())
showinfo(title="提示", message="加入成功!")
return True
@staticmethod
def delete_student(sno):
result = StudentDao.query_student(sno) # 根据学号查询学生
if result is None:
showerror(title="错误", message="不存在该学生!")
return
sql = "DELETE FROM t_student WHERE sno = %s"
StudentDao.update_student(sql, sno)
showinfo(title="提示", message="删除成功!")
return True
@staticmethod
def query_student(sno, list_entry):
result = StudentDao.query_student(sno) # 根据学号查询学生
if result is None:
showwarning(title="警告", message="未查询到相关学生信息!")
return
list_entry[0].insert(INSERT, result[2])
list_entry[1].insert(INSERT, result[3])
list_entry[2].insert(INSERT, result[4])
list_entry[3].insert(INSERT, result[5])
list_entry[4].insert(INSERT, result[6])
@staticmethod
def update_student(sno, list_entry):
result = StudentDao.query_student(sno) # 根据学号查询学生
if result is None:
showerror(title="错误", message="不存在该学生!")
return
sql = "UPDATE t_student SET sname = %s,sex = %s,age = %s,phone = %s,dormNo = %s WHERE sno = %s"
StudentDao.update_student(sql, list_entry[0].get(), list_entry[1].get(), list_entry[2].get(),
list_entry[3].get(), list_entry[4].get(), sno)
showinfo(title="提示", message="修改成功!")
return True
@staticmethod
def query_all(lb):
result = StudentDao.query_all()
for row in result:
lb.insert(END,
"ID:%s 学号:%s 姓名:%s 性别:%s 年龄:%s 电话:%s 宿舍号:%s" % (
row[0], row[1], row[2], row[3], row[4], row[5], row[6]))
@staticmethod
def to_excel():
data = {}
list_Id = []
list_sno = []
list_name = []
list_sex = []
list_age = []
list_phone = []
list_dormNo = []
for row in StudentDao.query_all():
list_Id.append(row[0])
list_sno.append(row[1])
list_name.append(row[2])
list_sex.append(row[3])
list_age.append(row[4])
list_phone.append(row[5])
list_dormNo.append(row[6])
data['ID'] = list_Id
data['学号'] = list_sno
data['姓名'] = list_name
data['性别'] = list_sex
data['年龄'] = list_age
data['电话'] = list_phone
data['宿舍'] = list_dormNo
ExcelUtils.to_excel(data)
showinfo(title="提示", message="导出成功!")

@ -0,0 +1,29 @@
from tkinter.messagebox import *
from dao.UserDao import UserDao
class UserService:
@staticmethod
def login_dispose(user_name, password):
user = UserDao.query_user(user_name)
if user is None:
showwarning(title="警告", message="不存在当前用户!\n请先注册!")
return
if password != user[2]:
showwarning(title="警告", message="密码错误!")
return
showinfo(title="提示", message="登录成功!")
return True
@staticmethod
def register_dispose(user_name, password):
user = UserDao.query_user(user_name)
if user is not None:
showwarning(title="警告", message="该用户名已使用!")
return
sql = "INSERT INTO t_user(user_name,user_password) VALUES (%s,%s);"
UserDao.update_user(sql, user_name, password)
showinfo(title="提示", message="注册成功!")
return True

@ -0,0 +1,204 @@
from tkinter import *
from dao.UserDao import UserDao
from service.StudentService import *
from service.UserService import UserService
class StudentUI:
root_window = Tk() # 根容器
left_frame = None # 左侧容器
right_frame = None # 右侧容器
list_entry = [] # 存放Entry组件用于参数传递和清空按钮的触发
@staticmethod
def init_login():
StudentUI.clear_frame(StudentUI.root_window) # 清空容器
StudentUI.root_window.title("登录界面")
width = 220 # 窗口的宽度
height = 140 # 窗口的高度
screen_width = StudentUI.root_window.winfo_screenwidth() # 获得屏幕宽度
screen_height = StudentUI.root_window.winfo_screenheight() # 获得屏幕高度
size_geo = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2,
(screen_height - height) / 2)
StudentUI.root_window.geometry(size_geo) # 设置窗口的大小、位置(居中)
label_1 = Label(StudentUI.root_window, text="用户名:") # 定义组件
label_2 = Label(StudentUI.root_window, text="密码:")
entry_1 = Entry(StudentUI.root_window, bd=5)
entry_2 = Entry(StudentUI.root_window, bd=5, show="*")
label_3 = Label(StudentUI.root_window, text="") # 为美化界面
label_4 = Label(StudentUI.root_window, text="")
label_1.grid(row=1, column=0) # 以网格布局的形式加入到root_window中
entry_1.grid(row=1, column=1)
label_3.grid(row=2, column=0)
label_2.grid(row=3, column=0)
entry_2.grid(row=3, column=1)
label_4.grid(row=4, column=0)
button_1 = Button(StudentUI.root_window, text="登录", command=lambda: StudentUI.submit_button(
lambda: UserService.login_dispose(entry_1.get(), entry_2.get()), StudentUI.init_root)) # 按钮
button_2 = Button(StudentUI.root_window, text="注册", command=StudentUI.init_register)
button_1.grid(row=5, column=0)
button_2.grid(row=5, column=1)
StudentUI.root_window.mainloop()
@staticmethod
def init_register():
StudentUI.clear_frame(StudentUI.root_window) # 清空容器
StudentUI.root_window.title("注册界面")
width = 220 # 窗口的宽度
height = 140 # 窗口的高度
screen_width = StudentUI.root_window.winfo_screenwidth() # 获得屏幕宽度
screen_height = StudentUI.root_window.winfo_screenheight() # 获得屏幕高度
size_geo = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2,
(screen_height - height) / 2)
StudentUI.root_window.geometry(size_geo) # 设置窗口的大小、位置(居中)
label_1 = Label(StudentUI.root_window, text="用户名:") # 定义组件
label_2 = Label(StudentUI.root_window, text="密码:")
entry_1 = Entry(StudentUI.root_window, bd=5)
entry_2 = Entry(StudentUI.root_window, bd=5, show="*")
label_3 = Label(StudentUI.root_window, text="") # 为美化界面
label_4 = Label(StudentUI.root_window, text="")
label_1.grid(row=1, column=0) # 以网格布局的形式加入到root_window中
entry_1.grid(row=1, column=1)
label_3.grid(row=2, column=0)
label_2.grid(row=3, column=0)
entry_2.grid(row=3, column=1)
label_4.grid(row=4, column=0)
button_1 = Button(StudentUI.root_window, text="提交", command=lambda: StudentUI.submit_button(
lambda: UserService.register_dispose(entry_1.get(), entry_2.get()), StudentUI.init_login)) # 按钮
button_2 = Button(StudentUI.root_window, text="返回登录", command=StudentUI.init_login)
button_1.grid(row=5, column=0)
button_2.grid(row=5, column=1)
StudentUI.root_window.mainloop()
@staticmethod
def init_root():
StudentUI.clear_frame(StudentUI.root_window) # 清空容器
StudentUI.root_window.title("学生信息管理系统") # 设置标题
width = 700 # 窗口的宽度
height = 400 # 窗口的高度
screen_width = StudentUI.root_window.winfo_screenwidth() # 获得屏幕宽度
screen_height = StudentUI.root_window.winfo_screenheight() # 获得屏幕高度
size_geo = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2,
(screen_height - height) / 2)
StudentUI.root_window.geometry(size_geo) # 设置窗口的大小、位置(居中)
StudentUI.left_frame = Frame(StudentUI.root_window)
StudentUI.right_frame = Frame(StudentUI.root_window)
StudentUI.left_frame.place(width=width / 3, height=height) # 设置左侧容器
StudentUI.right_frame.place(width=width / 3 * 2, height=height, x=width / 3) # 设置右侧容器
menu = Menu(StudentUI.root_window) # 添加菜单
# tearoff=0是关闭第一行虚线
menu_1 = Menu(menu, tearoff=0)
menu.add_cascade(label="功能", menu=menu_1)
menu_2 = Menu(menu, tearoff=0)
menu.add_cascade(label="文件", menu=menu_2)
menu_3 = Menu(menu, tearoff=0)
menu.add_cascade(label="帮助", menu=menu_3)
menu_1.add_cascade(label="添加学生", command=StudentUI.add_student) # 添加菜单项
menu_1.add_cascade(label="删除学生", command=StudentUI.delete_student)
menu_1.add_cascade(label="修改学生", command=StudentUI.update_student)
menu_2.add_cascade(label="保存为Excel", command=StudentService.to_excel)
menu_3.add_cascade(label="关于", command=StudentUI.about)
StudentUI.root_window["menu"] = menu # 将菜单加入根容器
StudentUI.add_student() # 初始化默认界面
StudentUI.query_all()
StudentUI.root_window.mainloop() # 显示窗口
@staticmethod
def clear_frame(frame):
for widget in frame.winfo_children(): # 清空frame,防止组件重叠
widget.destroy()
if frame != StudentUI.right_frame:
StudentUI.list_entry.clear() # 清空列表
@staticmethod
def clear_entry():
for i in range(len(StudentUI.list_entry)):
StudentUI.list_entry[i].delete(0, 'end')
return True
@staticmethod
def add_student():
StudentUI.clear_frame(StudentUI.left_frame) # 清空容器
list_name = ['学号:', '姓名:', '性别:', '年龄:', '电话:', '宿舍号:'] # 标签列表
for i in range(len(list_name)): # 将组件实例化、加入到容器中
label = Label(StudentUI.left_frame, text=list_name[i])
entry = Entry(StudentUI.left_frame, bd=5)
label.grid(row=i, column=0)
entry.grid(row=i, column=1)
StudentUI.list_entry.append(entry)
button_1 = Button(StudentUI.left_frame, text="提交",
command=lambda: StudentUI.submit_button(
lambda: StudentService.add_student(StudentUI.list_entry),
StudentUI.query_all))
button_2 = Button(StudentUI.left_frame, text="清除",
command=lambda: StudentUI.clear_entry())
button_1.grid(row=len(list_name), column=0)
button_2.grid(row=len(list_name), column=1)
@staticmethod
def delete_student():
StudentUI.clear_frame(StudentUI.left_frame) # 清空容器
label = Label(StudentUI.left_frame, text="学号:")
label.grid(row=0, column=0)
entry = Entry(StudentUI.left_frame, bd=5)
entry.grid(row=0, column=1)
StudentUI.list_entry.append(entry)
button_1 = Button(StudentUI.left_frame, text="提交", command=lambda: StudentUI.submit_button(
lambda: StudentService.delete_student(entry.get()),
StudentUI.query_all))
button_2 = Button(StudentUI.left_frame, text="清除", command=lambda: StudentUI.clear_entry())
button_1.grid(row=1, column=0)
button_2.grid(row=1, column=1)
@staticmethod
def update_student():
StudentUI.clear_frame(StudentUI.left_frame) # 清空容器
label = Label(StudentUI.left_frame, text='学号')
entry = Entry(StudentUI.left_frame, bd=5)
label.grid(row=0, column=0)
entry.grid(row=0, column=1)
button_1 = Button(StudentUI.left_frame, text="查询",
command=lambda: StudentUI.submit_button(StudentUI.clear_entry,
lambda: StudentService.query_student(entry.get(),
StudentUI.list_entry)))
button_2 = Button(StudentUI.left_frame, text="清除", command=lambda: entry.delete(0, 'end'))
button_1.grid(row=1, column=0)
button_2.grid(row=1, column=1)
list_name = ['姓名:', '性别:', '年龄:', '电话:', '宿舍号:']
for i in range(len(list_name)): # 将组件实例化、加入到容器中
label_2 = Label(StudentUI.left_frame, text=list_name[i])
entry_2 = Entry(StudentUI.left_frame, bd=5)
label_2.grid(row=i + 2, column=0) # 前面的学号和查询按钮占了两行所以i要加2
entry_2.grid(row=i + 2, column=1)
StudentUI.list_entry.append(entry_2)
button_1 = Button(StudentUI.left_frame, text="提交",
command=lambda: StudentUI.submit_button(
lambda: StudentService.update_student(entry.get(), StudentUI.list_entry),
StudentUI.query_all))
button_2 = Button(StudentUI.left_frame, text="清除", command=lambda: StudentUI.clear_entry())
button_1.grid(row=len(list_name) + 2, column=0)
button_2.grid(row=len(list_name) + 2, column=1)
@staticmethod
def query_all():
StudentUI.clear_frame(StudentUI.right_frame) # 清空容器
scrollBary = Scrollbar(StudentUI.right_frame, orient=VERTICAL) # 滚动条初始化scrollBary为垂直滚动条scrollBarx为水平滚动条
scrollBarx = Scrollbar(StudentUI.right_frame, orient=HORIZONTAL)
scrollBary.pack(side=RIGHT, fill=Y) # 靠右充满Y轴
scrollBarx.pack(side=BOTTOM, fill=X) # 靠下充满X轴
lb = Listbox(StudentUI.right_frame, width=111, height=32, )
lb.pack()
scrollBary.config(command=lb.yview) # 滚动条与页面内容的位置同步
scrollBarx.config(command=lb.xview)
# 调用方法
StudentService.query_all(lb)
@staticmethod
def submit_button(method_1, method_2):
if method_1() is not None:
method_2()
@staticmethod
def about():
showinfo(title="关于", message="en~~~~\n好像没啥可以说的....\n")

@ -0,0 +1,23 @@
import os
import pandas as pd
class ExcelUtils:
file_path = 'output.xlsx'
@staticmethod
def red_excel():
if not os.path.exists(ExcelUtils.file_path):
return
# 从Excel文件中读取数据
data = pd.read_excel('output.xlsx')
return data
@staticmethod
def to_excel(data):
# 将数据转换为DataFrame
df = pd.DataFrame(data)
# 导出到Excel文件
df.to_excel(ExcelUtils.file_path, index=False)
print("导出成功!")

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pythonProject100.iml" filepath="$PROJECT_DIR$/.idea/pythonProject100.iml" />
</modules>
</component>
</project>

@ -1,532 +0,0 @@
import pymysql
from tkinter import ttk
import tkinter as tk
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') # 这里的乘是小x
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') # 这里的乘是小x
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("localhost", "root", "123456", "student") # 打开数据库连接
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') # 这里的乘是小x
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.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("localhost", "root", "123456", "student") # 打开数据库连接
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.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=150, anchor='center') # 表示列,不显示
self.tree.column("姓名", width=150, 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 = []
# 打开数据库连接
db = pymysql.connect("localhost", "root", "root", "student")
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])
# print(self.id)
# print(self.name)
# print(self.gender)
# print(self.age)
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))): # 写入数据
self.tree.insert('', i, values=(self.id[i], self.name[i], self.gender[i], self.age[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', 20))
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.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_title = Label(self.frame_right_top, text="操作:", font=('Verdana', 20))
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_title.grid(row=1, column=0, pady=10)
self.right_top_button1.grid(row=2, column=0, padx=20, pady=10)
self.right_top_button2.grid(row=3, column=0, padx=20, pady=10)
self.right_top_button3.grid(row=4, column=0, padx=20, pady=10)
# 整体区域定位
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) # 捕捉右上角关闭点击
self.window.mainloop() # 进入消息循环
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.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() != '':
# 打开数据库连接
db = pymysql.connect("localhost", "root", "root", "student")
cursor = db.cursor() # 使用cursor()方法获取操作游标
sql = "INSERT INTO student_k(id, name, gender, age) \
VALUES ('%s', '%s', '%s', '%s')" % \
(self.var_id.get(), self.var_name.get(), self.var_gender.get(), self.var_age.get()) # SQL 插入语句
try:
cursor.execute(sql) # 执行sql语句
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.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.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("localhost", "root", "root", "student")
cursor = db.cursor() # 使用cursor()方法获取操作游标
sql = "UPDATE student_k SET name = '%s', gender = '%s', age = '%s' \
WHERE id = '%s'" % (
self.var_name.get(), self.var_gender.get(), self.var_age.get(), self.var_id.get()) # SQL 插入语句
try:
cursor.execute(sql) # 执行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.tree.item(self.tree.selection()[0], values=(
self.var_id.get(), self.var_name.get(), self.var_gender.get(),
self.var_age.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("localhost", "root", "root", "student")
cursor = db.cursor() # 使用cursor()方法获取操作游标
sql = "DELETE FROM student_k WHERE id = '%s'" % (self.row_info[0]) # SQL 插入语句
try:
cursor.execute(sql) # 执行sql语句
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]
print(self.id)
self.tree.delete(self.tree.selection()[0]) # 删除所选行
print(self.tree.get_children())
# 学生查看信息界面
class StudentView:
def __init__(self, parent_window, student_id):
parent_window.destroy() # 销毁主界面
self.window = tk.Tk() # 初始框的声明
self.window.title('关于')
self.window.geometry('300x450') # 这里的乘是小x
label = tk.Label(self.window, text='学生信息查看', bg='green', font=('Verdana', 20), width=30, height=2)
label.pack(pady=20)
self.id = '学号:' + ''
self.name = '姓名:' + ''
self.gender = '性别:' + ''
self.age = '年龄:' + ''
# 打开数据库连接
db = pymysql.connect("localhost", "root", "root", "student")
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]
except:
print("Error: unable to fetch data")
db.close() # 关闭数据库连接
Label(self.window, text=self.id, font=('Verdana', 18)).pack(pady=5)
Label(self.window, text=self.name, font=('Verdana', 18)).pack(pady=5)
Label(self.window, text=self.gender, font=('Verdana', 18)).pack(pady=5)
Label(self.window, text=self.age, font=('Verdana', 18)).pack(pady=5)
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) # 显示主窗口 销毁本窗口
# About页面
class AboutPage:
def __init__(self, parent_window):
parent_window.destroy() # 销毁主界面
self.window = tk.Tk() # 初始框的声明
self.window.title('关于')
self.window.geometry('300x450') # 这里的乘是小x
label = tk.Label(self.window, text='学生信息管理系统', bg='green', font=('Verdana', 20), width=30, height=2)
label.pack()
Label(self.window, text='作者:清晨的光明', font=('Verdana', 18)).pack(pady=30)
Label(self.window, text='blog.csdn.net/kdongyi', font=('Verdana', 18)).pack(pady=5)
Button(self.window, text="返回首页", width=8, font=tkFont.Font(size=12), command=self.back).pack(pady=100)
self.window.protocol("WM_DELETE_WINDOW", self.back) # 捕捉右上角关闭点击
self.window.mainloop() # 进入消息循环
def back(self):
StartPage(self.window) # 显示主窗口 销毁本窗口
if __name__ == '__main__':
try:
# 打开数据库连接 连接测试
db = pymysql.connect("localhost", "root", "root", "student")
# 使用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)
except:
messagebox.showinfo('错误!', '连接数据库失败!')

Binary file not shown.
Loading…
Cancel
Save