微信公众号:愤怒的it男,超多Python技术干货文章。
一、前言
Python的开发方向有很多,比如爬虫采集、数据分析、机器学习等,因此Python给大家的印象都是处理数据的。实际上,Python也可以开发带有GUI界面的软件应用。这里,我就是使用Python+Tkinter写一个带有GUI界面的学生管理系统,功能齐全,代码仅200行左右。
二、作品展示
三、原型设计
学生管理系统的界面分为主界面和信息输入框两部分,绝大多数操作在主界面中完成,只有增加或修改学生数据时会显示信息输入框。
(一)主界面
我将主界面分为上中下三部分:上部分为搜索条件区,用来输入搜索条件;中部分为操作按钮区,用来进行增删改查操作;下部分为数据展示区,用来展示结果数据。
(二)信息输入框
信息输入框的原型设计就比较简单,八个接收输入的输入框,一个保存按钮。信息输入框只有点击增加或者修改按钮是才会显示。
四、代码编写
根据解耦设计原则,我将学生管理系统的GUI界面和学生数据处理分别在ui.py
和student_manager.py
两个源码文件中实现。
(一)源码文件(student_manager.py)
1、导入所需的库
import csv
2、定义学生管理类(StudentManager)
class StudentManager:
3、StudentManager中定义初始化方法
def __init__(self):
with open('students.csv', 'r', encoding='utf-8') as file:
csv_reader = csv.reader(file)
self.students = [row for row in csv_reader if any(row)]
4、StudentManager中定义增加操作方法
def add(self, student):
for s in self.students:
if s[0] == student[0]:
return [False, '已存在该学号学生!增加失败!']
self.students.append(student)
with open('students.csv', 'w', encoding='utf-8') as file:
writer = csv.writer(file)
writer.writerows(self.students)
return [True, '增加成功!']
5、StudentManager中定义删除操作方法
def delete(self, student):
for i,s in enumerate(self.students):
if s[0] == student[0]:
del self.students[i]
with open('students.csv', 'w', encoding='utf-8') as file:
writer = csv.writer(file)
writer.writerows(self.students)
return [True, '删除成功!']
return [False, '不存在该学号学生!删除失败!']
6、StudentManager中定义修改操作方法
def modify(self, student):
for i,s in enumerate(self.students):
if s[0] == student[0]:
self.students[i] = student
with open('students.csv', 'w', encoding='utf-8') as file:
writer = csv.writer(file)
writer.writerows(self.students)
return [True, '修改成功!']
return [False, '不存在该学号学生!修改失败!']
7、StudentManager中定义搜索操作方法
def search(self, student):
condition_num = len(list(filter(lambda x: x!='', student)))
if condition_num!=0:
data = []
for s in self.students:
ok = True
for i,v in enumerate(s):
if student[i]!='':
ok = ok and (v == student[i])
if ok:
data.append(s)
return data
else:
return self.students
8、创建一个学生管理实例(studentManager)
studentManager = StudentManager()
(二)源码文件(ui.py)
1、导入所需的库
import student_manager
import math
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
2、创建主界面窗口
window = tk.Tk()
window.title('学籍管理系统(微信公众号:愤怒的it男)')
window.iconbitmap('favicon.ico')
window.geometry('800x400')
3、主界面窗口添加选项卡
notebook = ttk.Notebook(window)
tab1 = tk.Frame(notebook, width=800, height=380)
tab2 = tk.Frame(notebook, bg='white', width=800, height=380)
notebook.add(tab1, text='学籍管理')
notebook.add(tab2, text='其他')
notebook.pack()
4、学籍管理选项卡添加搜索条件区
frame1 = tk.Frame(tab1, bg='white')
frame1.pack()
query = [None]*8
field = ['学号','姓名','性别','年级','电话','院系','专业','备注']
columns = ["num", "name", "sex", "grade", "telephone", "department", "major", "remark"]
for i,f in enumerate(field):
label_text = tk.Label(frame1, text=f+':', font=('宋体',10))
label_text.grid(row=math.floor(i/4), column=i%4*2, padx=5, pady=5)
query[i] = tk.StringVar()
entry = tk.Entry (frame1, width=16, textvariable=query[i])
entry.grid(row=math.floor(i/4), column=i%4*2+1, padx=5, pady=5)
5、学籍管理选项卡添加操作按钮区
def refresh_treeview(data):
tree.delete(*tree.get_children())
for i,item in enumerate(data):
tree.insert("", tk.END, text=str(i+1), values=tuple(item))
frame2 = tk.Frame(tab1, width=800, height=40)
frame2.pack()
def click_add():
popup = tk.Toplevel(window)
createToplevel(popup, 'add', ['']*8)
button1 = tk.Button(frame2, text='增加', font=('宋体',10,'bold'), width=8, height=1, command=click_add)
button1.grid(row=0, column=0, padx=5, pady=10)
def click_delete():
selected_items = tree.selection()
if selected_items:
data = tree.item(selected_items[0])['values']
data = list(map(lambda x: str(x), data))
result = student_manager.studentManager.delete(data)
messagebox.showinfo(title='温馨提示', message=result[1])
result = student_manager.studentManager.search(['']*8)
refresh_treeview(result)
else:
txt = '删除失败!未选择删除数据!'
messagebox.showinfo(title='温馨提示', message=txt)
button2 = tk.Button(frame2, text='删除', font=('宋体',10,'bold'), width=8, height=1, command=click_delete)
button2.grid(row=0, column=1, padx=5, pady=10)
def click_modify():
selected_items = tree.selection()
if selected_items:
data = tree.item(selected_items[0])['values']
data = list(map(lambda x: str(x), data))
popup = tk.Toplevel(window)
createToplevel(popup, 'modify', data)
else:
txt = '请选择需要修改的数据!'
messagebox.showinfo(title='温馨提示', message=txt)
button3 = tk.Button(frame2, text='修改', font=('宋体',10,'bold'), width=8, height=1, command=click_modify)
button3.grid(row=0, column=2, padx=5, pady=10)
def click_search():
data = list(map(lambda x: str(x.get()), query))
result = student_manager.studentManager.search(data)
refresh_treeview(result)
button4 = tk.Button(frame2, text='搜索', font=('宋体',10,'bold'), width=8, height=1, command=click_search)
button4.grid(row=0, column=3, padx=5, pady=10)
6、学籍管理选项卡添加数据展示区
frame3 = tk.Frame(tab1, bg='white', width=800, height=260)
frame3.pack()
style = ttk.Style()
style.configure("Treeview", rowheight=20)
style.configure("Treeview.Heading", font=('Arial', 11, 'bold'))
tree = ttk.Treeview(frame3, height=12, selectmode="browse", style="Treeview")
tree.pack()
tree["columns"] = tuple(columns)
tree.heading("#0", text="序号")
tree.column("#0", width=40)
for i,v in enumerate(field):
tree.heading(columns[i], text=v)
tree.column(columns[i], width=95, anchor="center")
result = student_manager.studentManager.search(['']*8)
refresh_treeview(result)
7、其他选项卡添加公众号图片(愤怒的it男)
image = tk.PhotoImage(file='image.png')
image_label = tk.Label(tab2, image=image)
image_label.pack()
8、创建信息输入框
def createToplevel(popup, operation, select_data):
def on_closing():
popup.destroy()
window.attributes("-disabled", False)
window.attributes("-disabled", True)
popup.title("学生信息")
popup.iconbitmap('favicon.ico')
popup.geometry("550x150")
popup.protocol("WM_DELETE_WINDOW", on_closing)
info = [None]*8
field = ['学号','姓名','性别','年级','电话','院系','专业','备注']
for i,f in enumerate(field):
label_text = tk.Label(popup, text=f+':', font=('宋体',10))
label_text.grid(row=math.floor(i/3), column=i%3*2, padx=5, pady=5)
info[i] = tk.StringVar()
info[i].set(select_data[i])
entry = tk.Entry (popup, width=16, textvariable=info[i])
entry.grid(row=math.floor(i/3), column=i%3*2+1, padx=5, pady=5)
def click_save(operation):
empty_num = len(list(filter(lambda x: str(x.get())=='', info)))
result = [False]
if empty_num==0:
data = list(map(lambda x: str(x.get()), info))
if operation == 'add':
result = student_manager.studentManager.add(data)
if operation == 'modify':
result = student_manager.studentManager.modify(data)
on_closing()
if empty_num==0 and result[0]:
messagebox.showinfo(title='温馨提示', message=result[1])
elif empty_num!=0:
txt = '保存失败!存在空字段!'
messagebox.showinfo(title='温馨提示', message=txt)
elif not result[0]:
messagebox.showinfo(title='温馨提示', message=result[1])
else:
txt = '保存失败!存在其他异常!'
messagebox.showinfo(title='温馨提示', message=txt)
result = student_manager.studentManager.search(['']*8)
refresh_treeview(result)
button = tk.Button(popup, text='保存', font=('宋体',10,'bold'), width=8, height=1, command=lambda:click_save(operation))
button.grid(row=3, column=3, padx=5, pady=10)
9、开启事件循环检测
window.mainloop()
五、源码下载
公众号(愤怒的it男)后台回复三位数字:001,即可获取源码资源包。
微信公众号:愤怒的it男,超多Python技术干货文章。