实验4 Python数据分析与GUI( 三 )


实验4.6:综合GUI编程-学生管理平台
题目描述:利用、、.和os库完成5项编程任务 。
(1)使用.exe工具(工具来源参照第3次实验的子实验)设计一个名为test.db数据库,库中创建两张数据表user(uid, upwd)和(sid, sname, ssex, sage, ) 。输入对应数据如图6-1和图6-2所示 。
(2)设计一个用户登录类,布局如图6-3所示用户登录界面,实现“登录”和“退出”功能 。
(3)设计一个主控管理类sMain,布局如图6-4所示主控管理界面,设计一级水平主菜单4项,包括“学生管理”、“”“课程管理”、“成绩管理”和“退出系统” 。其中主菜单“成绩管理”可设计二级下拉菜单3项,包括“录入成绩”、“查询成绩”和“统计成绩” 。(可以选做:下拉菜单“查询成绩”自行设计三级级联菜单2项,包括“理论成绩”和“实验成绩” 。)实现菜单的功能设计与层次管理 。
(4)设计一个学生管理类,布局如图6-5所示学生管理界面,实现学生“录入”、“删除”、“修改”、“查询”、“查看”和关闭6个子功能 。(以下给出单个“查询”和所有“查看”功能图示)
(5)通过菜单集成关联窗体 。程序运行流程是:首先启动登录界面,查验数据库中用户名和密码有效后,然后才能进入主控管理界面,点击“学生管理”一级主菜单,可弹出显示学生管理界面,完成学生管理添、删、改、查基本功能 。(另外选做:实现“课程管理”和“成绩管理”基本功能 。)
提示:
(1)数据表字段类型可全部设置为类型,即字符串类型;
(2)利用生成窗体、标签、文本框、命令按钮;
(3)利用grid和place实现窗体布局和控件定位;
(4)利用GUI面向对象编程方式实现GUI编程封装 。
(5)利用SQL语句、、和实现添、删、改、查基本管理功能 。
import tkinter as Tkfrom tkinter import *import tkinter.messagebox as messageboximport sqlite3import os################################################################################import tkinter as Tkclass sLogin:"""登录界面"""# ----------------------------------------------------------------------def __init__(self, login):# 构造初始"""登录界面初始"""self.frmLogin = loginself.frmLogin.geometry("320x200+380+200")self.frmLogin.title("用户登录")self.frame = Tk.Frame(self.frmLogin)# windows开发:frame, web开发:(page)self.gridFrame()# ----------------------------------------------------------------------def gridFrame(self):# 界面布局"""登录界面布局"""self.uid = StringVar()self.uid.set("mzx")self.upwd = StringVar()self.upwd.set("123")Label(self.frame).grid(row=0)# 让界面先空一行Label(self.frame, text="学生管理平台", fg="blue", font=("黑体", 20, "bold")).grid(row=1, columnspan=2)Label(self.frame, text="用户名", width=5).grid(row=2, column=0, padx=10, pady=10, sticky='e')Entry(self.frame, textvariable=self.uid).grid(row=2, column=1, pady=10, sticky='w')Label(self.frame, text="密码", width=5).grid(row=3, column=0, padx=10, pady=5,sticky='e')Entry(self.frame, textvariable=self.upwd,show='*').grid(row=3, column=1, pady=5, sticky='w')Button(self.frame, text="登录", width=13,command=self.onLogin).grid(row=4, column=0, pady=10, sticky='w')Button(self.frame, text="退出", width=13,command=self.onExit).grid(row=4, column=1, pady=5, sticky='e')self.frame.pack()# ----------------------------------------------------------------------def onLogin(self):"""登录进入"""self.conn = sqlite3.connect("test.db")# 连接数据库cmd = self.conn.cursor()sql = "select uid, upwd from user where uid='%s'" % self.uid.get()cmd.execute(sql)# 执行数据库ds = cmd.fetchall()# 接收全部信息if len(ds) == 0:# 值为0,表示没有找到记录, 值为1,表示有一条记录messagebox.showerror("登录失败", "账户不存在")else:xuid, xupwd = ds[0]if xuid == self.uid.get() and xupwd == self.upwd.get():self.hide()# 隐藏窗体root = Tk.Tk()# 主窗体,作为一级窗体比较合适sMain(root)root.mainloop()else:messagebox.showwarning("登录失败", "密码错误")self.conn.close()# 关闭数据库# ----------------------------------------------------------------------def hide(self):"""隐藏窗体"""self.frame.destroy()self.frmLogin.withdraw()# ----------------------------------------------------------------------def onExit(self):"""退出登录"""os._exit(0)# 退出系统################################################################################class sMain(object):"""主控界面"""# ----------------------------------------------------------------------def __init__(self, parent):self.root = parentself.root.geometry("1220x600+20+10")self.root.title("学生管理平台v1.0")self.frame = Tk.Frame(self.root)self.menuFrame()# ----------------------------------------------------------------------def menuFrame(self):"""设计菜单"""self.main = Tk.Menu(self.root)# 创建主菜单# self.subMenu1=Menu(self.main)#创建下拉子菜单1:学生管理# self.subMenu2=Menu(self.main)#创建下拉子菜单2:课程管理self.subMenu3 = Menu(self.main)# 创建下拉子菜单3:成绩管理self.subMenu3.add_command(label="录入成绩")self.subMenu3.add_command(label="查询成绩")self.subMenu3.add_command(label="统计成绩", command=self.onCalScore)self.main.add_cascade(label="学生管理", command=self.onOpenStudent)self.main.add_cascade(label="课程管理")self.main.add_cascade(label="成绩管理", menu=self.subMenu3)self.main.add_cascade(label="退出系统", command=self.onExit)self.root["menu"] = self.main# 显示菜单self.frame.pack()# ----------------------------------------------------------------------def onOpenStudent(self):"""打开子窗体"""sub = Tk.Toplevel()# 弹出顶级窗体,作为二级子窗体比较合适# sub=Tk.Tk()#主窗口,一般作为一级窗口sManage(sub)# ----------------------------------------------------------------------def onCalScore(self):"""统计成绩"""pass# ----------------------------------------------------------------------def onExit(self):"""退出系统"""os._exit(0)# 退出系统################################################################################class sManage():"""学生管理"""# ----------------------------------------------------------------------def __init__(self, child):"""学生界面初始"""self.frmStudent = childself.frmStudent.geometry("600x400+40+70")self.frmStudent.title("学生管理")self.frame = Tk.Frame(self.frmStudent)self.gridFrame()# ----------------------------------------------------------------------def gridFrame(self):"""学生界面布局"""self.sid = StringVar()self.sid.set('')self.sname = StringVar()self.sname.set('')self.ssex = StringVar()self.ssex.set('')self.sage = StringVar()self.sage.set('')# 编程心得:年龄类型也做成字符串self.sclass = StringVar()self.sclass.set('')# 必须使用grid布局网格,配合使用place精确定位Label(self.frame).grid(row=0)# 界面空一行Label(self.frame, text="学生管理平台", fg="blue",font=("黑体", 20, "bold")).grid(row=1, columnspan=4)# 使用grid布局Label(self.frame, text="学号", fg="red").grid(row=2, column=0, pady=5, sticky='w')Entry(self.frame, textvariable=self.sid).place(x=48, y=63)# 使用place定位Label(self.frame, text="姓名").grid(row=3, column=0, pady=5, sticky='w')Entry(self.frame, textvariable=self.sname).place(x=48, y=96)# 使用place定位Label(self.frame, text="性别").place(x=231, y=96)# 使用place定位Entry(self.frame, textvariable=self.ssex).place(x=281, y=96)# 使用place定位Label(self.frame, text="年龄").grid(row=4, column=0, pady=5, sticky='w')Entry(self.frame, textvariable=self.sage).place(x=48, y=129)# 使用place定位Label(self.frame, text="班级").place(x=231, y=129)# 使用place定位Entry(self.frame, textvariable=self.sclass).place(x=281, y=129)# 使用place定位Button(self.frame, text="录入", width=10,command=self.onInsert).place(x=0, y=165)# 使用place定位Button(self.frame, text="删除", width=10,command=self.onDelete).place(x=85, y=165)Button(self.frame, text="修改", width=10,command=self.onUpdate).place(x=170, y=165)Button(self.frame, text="查询", width=10,command=self.onSelect).place(x=255, y=165)Button(self.frame, text="查看", width=10,command=self.onLook).place(x=340, y=165)Button(self.frame, text="关闭", width=10,command=self.onHide).place(x=425, y=165)self.vShow = StringVar()self.vShow.set('')# Text(self.frame,textvariable=self.v,width=60,height=23).grid(row=5,columnspan=4,pady=50,sticky='e')Listbox(self.frame, listvariable=self.vShow,width=72, height=9).grid(row=5, columnspan=4, pady=50, sticky='e')# height:是行数self.frame.pack()# ----------------------------------------------------------------------def onInsert(self):"""录入学生"""self.conn = sqlite3.connect("test.db")# 连接数据库self.cmd = self.conn.cursor()# 检查记录是否存在,不存在才能录入新学生记录sql = "select sid, sname, ssex, sage, sclass from student where sid='%s'" % self.sid.get()self.cmd.execute(sql)# 执行数据库ds = self.cmd.fetchall()# 接收全部信息if len(ds) == 1:# 值为0,表示没有找到记录, 值为1,表示有一条记录messagebox.showerror("录入失败", "学生" + self.sid.get() + "存在,不允许重复录入...")else:sql = "insert into student(sid,sname,ssex,sage,sclass) values('%s','%s','%s','%s','%s')" \% (self.sid.get(), self.sname.get(), self.ssex.get(), self.sage.get(), self.sclass.get())self.cmd.execute(sql)self.conn.commit()# 提交数据messagebox.showinfo("录入成功", "录入学生" + self.sid.get() + "成功...")self.cmd.close()self.conn.close()# 关闭数据库# ----------------------------------------------------------------------def onDelete(self):"""删除学生"""self.conn = sqlite3.connect("test.db")# 连接数据库self.cmd = self.conn.cursor()# 检查记录是否存在,存在才能删除学生记录sql = "select sid, sname, ssex, sage, sclass from student where sid='%s'" % self.sid.get()self.cmd.execute(sql)# 执行数据库ds = self.cmd.fetchall()# 接收全部信息if len(ds) == 0:# 值为0,表示没有找到记录, 值为1,表示有一条记录messagebox.showerror("删除失败", "学生" + self.sid.get() + "不存在,删除失败...")else:sql = "delete from student where sid='%s'" % self.sid.get()self.cmd.execute(sql)self.conn.commit()# 提交数据messagebox.showinfo("删除成功", "删除学生" + self.sid.get() + "成功...")self.cmd.close()self.conn.close()# 关闭数据库# ----------------------------------------------------------------------def onUpdate(self):"""修改学生"""self.conn = sqlite3.connect("test.db")# 连接数据库self.cmd = self.conn.cursor()# 检查记录是否存在,存在才能修改学生记录sql = "select sid, sname, ssex, sage, sclass from student where sid='%s'" % self.sid.get()self.cmd.execute(sql)# 执行数据库ds = self.cmd.fetchall()# 接收全部信息if len(ds) == 0:# 值为0,表示没有找到记录, 值为1,表示有一条记录messagebox.showerror("修改失败", "学生" + self.sid.get() + "不存在,修改失败...")else:sql = "update student set sname='%s', ssex='%s', sage='%s', sclass='%s' where sid='%s'" \% (self.sname.get(), self.ssex.get(), self.sage.get(), self.sclass.get(), self.sid.get())self.cmd.execute(sql)self.conn.commit()# 提交数据messagebox.showinfo("修改成功", "修改学生" + self.sid.get() + "成功...")self.cmd.close()self.conn.close()# 关闭数据库# ----------------------------------------------------------------------def onSelect(self):"""查询学生"""self.conn = sqlite3.connect("test.db")# 连接数据库self.cmd = self.conn.cursor()sql = "select sid, sname, ssex, sage, sclass from student where sid='%s'" % self.sid.get()self.cmd.execute(sql)# 执行数据库ds = self.cmd.fetchall()# 接收全部信息if len(ds) == 0:# 值为0,表示没有找到记录, 值为1,表示有一条记录messagebox.showerror("查询失败", "查询学生" + self.sid.get() + "不存在...")else:xsid, xsname, xssex, xsage, xsclass = ds[0]self.sid.set(xsid)self.sname.set(xsname)self.ssex.set(xssex)self.sage.set(xsage)self.sclass.set(xsclass)strResult = xsid+','+xsname+','+xssex+','+xsage+','+xsclass# 注意:不用空格,而用逗号分隔self.vShow.set(strResult)# 列表框中以空格分割元素进入列表中self.cmd.close()self.conn.close()# 关闭数据库def onLook(self):"""查看学生"""self.conn = sqlite3.connect("test.db")# 连接数据库self.cmd = self.conn.cursor()sql = "select sid, sname, ssex, sage, sclass from student"self.cmd.execute(sql)# 执行数据库ds = self.cmd.fetchall()# 接收全部信息if len(ds) == 0:# 值为0,表示没有找到记录, 值为1,表示有一条记录messagebox.showerror("查看失败", "查询学生" + self.sid.get() + "不存在...")else:strResult = ''for i in range(len(ds)):xsid, xsname, xssex, xsage, xsclass = ds[i]strResult += xsid+','+xsname+','+xssex+',' + \xsage+','+xsclass+' '# 注意:不用空格,而用逗号分隔self.vShow.set(strResult)# 列表框中以空格分割元素进入列表中self.cmd.close()self.conn.close()# 关闭数据库# ----------------------------------------------------------------------def onHide(self):"""隐藏窗体"""self.frame.destroy()self.frmStudent.withdraw()################################################################################if __name__ == "__main__":"""主程序启动入口"""login = Tk.Tk()sLogin(login)# 登录窗体为第一启动对象login.mainloop()