在现代企业中,一个简单的员工信息管理系统可以帮助我们轻松地查询、添加、修改、删除和统计员工信息。本节教程中将介绍如何通过Python的GUI图形库Tkinter,设计员工信息管理系统(Employee Information Management System)。
1、员工信息管理系统介绍
随着编程技术的发展,Python作为最受欢迎的编程语言,利用Python可以快速构建一个员工信息管理系统。该系统可以实现添加员工信息到Excel表格中(包括:工号、姓名、性别,年龄,部门,职务,手机号码),同时支持删除、查询和修改Excel表格中的员工信息,并将编辑后的数据内容保存到Excel表格中。运行该程序时,默认会在Python的运行工作目录下创建一个employee.xlsx文件,用于存储员工信息。
注意,运行该程序前,如果employee.xlsx文件已被双击打开,必须先关闭该Excel文件,否则会报错并自动退出程序。
登录界面默认账号为“admin”,密码为“123456”。
2、员工信息管理系统界面演示
登录账号:admin,密码:123456
3、代码实现
(1)安装pandas库
首先,确保你已经安装了pandas库。如果还没有安装,可以通过pip安装:
pip install pandas
(2)导入必要的库
import tkinter as tk
from tkinter import ttk, messagebox
from tkinter.ttk import Style, PanedWindow, Button, Treeview
import tkinter.font as tkFont
import pandas as pd
import sys, os, webbrowser
这里导入了Tkinter库用于创建GUI应用图形界面。pandas库是Python中用于数据分析和处理的核心库,这里我们利用pandas库读取Excel文件和将数据写入Excel文件。如果有一个多行列表(或者说是一个二维列表),我们可以使用pandas.DataFrame将这个列表转换为DataFrame,然后使用DataFrame.to_excel()方法将DataFrame写入Excel文件。
(3)员工信息管理系统的完整代码如下所示:
动手练一练:
import tkinter as tk
from tkinter import ttk, messagebox
from tkinter.ttk import Style, PanedWindow, Button, Treeview
import tkinter.font as tkFont
import pandas as pd
import sys, os, webbrowser
# 获取当前脚本文件所在的目录
default_directory = os.path.dirname(os.path.abspath(__file__))
# 将当前脚本文件所在的目录设置为工作目录
os.chdir(default_directory)
# 定义登录账号为“admin”,密码为“123456”
user_name = "admin"
password = "123456"
# 定义Excel文件名
name_file = 'employee.xlsx'
try:
# 检查Excel文件是否存在,如果不存在则自动在工作目录下创建“employee.xlsx”文件
if not os.path.exists(name_file):
# 创建新的DataFrame,定义列标题
df = pd.DataFrame(columns=['工号', '姓名', '性别', '年龄', '部门', '职务', '手机号码'])
# 写入标题到新的Excel文件
df.to_excel(name_file, index=False)
except:
pass
# 定于一个方法,用于检查工号是否规范,返回6位数字
def is_ID(ID):
return len(ID) == 6 and ID.isdigit()
# 定于一个方法,用于检查年龄是否规范,必须为正整数
def is_Age(Age):
return Age.isdigit() and 0 <= int(Age)
# 定义一个方法,用于写入文件
def save_excel(employee):
try:
# 创建DataFrame
df = pd.DataFrame(employee, columns=['工号', '姓名', '性别', '年龄', '部门', '职务', '手机号码'])
# 写入Excel文件,index=False表示不写入行索引到Excel文件中
df.to_excel(name_file, index=False)
except PermissionError:
# 如果Excel文件已经被打开,则捕获异常并弹出提示信息
messagebox.showinfo("提示", "employee.xlsx文件已经被打开,请先关闭...")
# 关闭主进程
sys.exit()
# 提示信息函数
def prompt_Add():
messagebox.showinfo("提示信息","添加成功")
def prompt_Search():
messagebox.showinfo("提示信息","查询成功")
def prompt_Del():
messagebox.showinfo("提示信息","删除成功")
def prompt_Mod():
messagebox.showinfo("提示信息","修改成功")
def prompt_Add_ID_Repeat():
messagebox.showinfo("提示信息","此工号已经存在,请勿重复添加!")
def prompt_Del_ID_None():
messagebox.showinfo("提示信息","此工号不存在,请重新输入!")
def prompt_Search_None():
messagebox.showinfo("提示信息","未查询到有关员工信息!")
def prompt_Add_ID():
messagebox.showinfo("提示信息","工号格式有误,请重新输入!")
def prompt_Add_Age():
messagebox.showinfo("提示信息","年龄格式有误,请重新输入!")
def prompt_Add_Class():
messagebox.showinfo("提示信息","班级格式有误,请重新输入!")
def prompt_Add_Telephone():
messagebox.showinfo("提示信息","电话格式有误,请重新输入!")
# 员工信息管理系统登录页面
class Root:
def __init__(self, window):
self.window = window
self.window.title("员工信息管理系统登录页面")
# 设置窗口居中
window_width = 550
window_height = 280
screen_width = self.window.winfo_screenwidth()
screen_height = self.window.winfo_screenheight()
x = (screen_width - window_width) / 2
y = (screen_height - window_height) / 2
self.window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
self.window.resizable(width=False, height=False)
self.frame = tk.Frame(self.window)
self.frame.pack()
self.login()
# 创建登录页面控件
def login(self):
# 创建左框架部分
left_frame = tk.Frame(self.frame, bg='#a3cdfd')
left_frame.pack(side=tk.LEFT, fill=tk.Y)
left_frame.pack_propagate(False)
# 创建右框架部分
right_frame = tk.Frame(self.frame, bg='#ffffff')
right_frame.pack(side=tk.RIGHT, fill=tk.Y)
# 在左侧放置说明文本
label_welcome_1 = tk.Label(left_frame, text='员工信息管理系统', font=('宋体', 20, 'bold'), bg='#a3cdfd', justify=tk.LEFT)
label_welcome_1.grid(row=0, column=0, padx=10, pady=30)
label_welcome_2 = tk.Label(left_frame, text='欢迎登录系统', font=('宋体', 20, 'bold'), bg='#a3cdfd', justify=tk.LEFT)
label_welcome_2.grid(row=1, column=0, padx=10, pady=30)
label_welcome_3 = tk.Label(left_frame, text='版本:V1.0.1', font=('宋体', 20, 'bold'), bg='#a3cdfd', justify=tk.LEFT)
label_welcome_3.grid(row=2, column=0, padx=10, pady=30)
# 在右侧设计登录窗口
login_title = tk.Label(right_frame, text='用户登录', font=('宋体', 20, 'bold'), bg='#ffffff', justify=tk.CENTER)
login_title.grid(row=0, column=0, columnspan=2, padx=10, pady=20)
user_name_label = tk.Label(right_frame, text='账号:', font=('宋体', 14), bg='#ffffff')
user_name_label.grid(row=1, column=0, padx=10, pady=20)
self.user_name_entry = tk.Entry(right_frame, highlightthickness=1, font=('宋体', 15), bg='#F3F3F4', width=15)
self.user_name_entry.grid(row=1, column=1, padx=10, pady=20)
user_password_label = tk.Label(right_frame, text='密码:', font=('宋体', 14), bg='#ffffff')
user_password_label.grid(row=2, column=0, padx=10, pady=20)
self.user_password_entry = tk.Entry(right_frame, highlightthickness=1,font=('宋体', 15), bg='#F3F3F4', show='*', width=15)
self.user_password_entry.grid(row=2, column=1, padx=10, pady=20)
button_login = tk.Button(right_frame, text="登录", font=('宋体', 13), bg="#a3cdfd", width=10, command=self.check)
button_login.grid(row=3, column=0, sticky="w", padx=10, pady=5)
quit_login = tk.Button(right_frame, text="退出", font=('宋体', 13), bg="#a3cdfd", width=10, command=self.window.quit)
quit_login.grid(row=3, column=1, sticky="e", padx=10, pady=5)
# 检查输入的账号和密码是否正确
def check(self):
if self.user_name_entry.get() == user_name and self.user_password_entry.get() == password:
messagebox.showinfo(title="登陆成功", message=f"欢迎登陆系统,{user_name}!")
self.frame.destroy()
Home(self.window)
return True
else:
messagebox.showwarning(title="登录失败", message="账号或密码错误")
self.user_password_entry.delete(0, tk.END)
return False
# 员工信息管理系统主页面
class Home:
def __init__(self, window):
self.window = window
self.window.title(f"当前管理员为{user_name}")
# 设置窗口居中
window_width = 1000
window_height = 600
screen_width = self.window.winfo_screenwidth()
screen_height = self.window.winfo_screenheight()
x = (screen_width - window_width) / 2
y = (screen_height - window_height) / 2
self.window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
self.window.resizable(width=False, height=False)
self.readExcel()
self.main()
self.query_result_list = []
# 读取Excel表格中的数据
def readExcel(self):
df = pd.read_excel(name_file, usecols="A:G", dtype=str)
# 把Excel中每一行存入一个列表
self.all_employee_list = df.values.tolist()
# 清除输入的所有内容
def del_Entry_content(self):
self.get_number.delete(0, tk.END)
self.get_name.delete(0, tk.END)
self.get_department.delete(0, tk.END)
self.get_position.delete(0, tk.END)
# 1.添加员工信息的主方法
def Add_Employee_Info(self):
# 获取输入的信息
number = self.Txt_ID.get()
names = self.Txt_Name.get()
gender = self.sex.get()
age = self.Txt_Age.get()
department = self.Txt_Department.get()
position = self.Txt_position.get()
mobile = self.Txt_Telephone.get()
# 检查输入信息是否规范
if not is_ID(number):
prompt_Add_ID()
return
# 判断工号是否重复
for i in self.all_employee_list:
if number in i[0]:
prompt_Add_ID_Repeat()
return
if not is_Age(age):
prompt_Add_Age()
return
# 用列表整合员工信息
Info_dict = [number, names, gender, age, department, position, mobile]
# 将列表存入总列表
self.all_employee_list.append(Info_dict)
# 添加成功
prompt_Add()
# 将信息写入文件
save_excel(self.all_employee_list)
self.show_all()
# 2.删除员工信息的主方法
def Del_Employee_Info(self):
# 获取输入的信息
number = self.Txt_ID.get()
# 检查输入信息是否规范
if not is_ID(number):
prompt_Add_ID()
return
# 用于指示是否删除的状态指标
Flag = True
# 遍历,删除员工信息
for i in self.all_employee_list:
if number in i[0]:
self.all_employee_list.remove(i)
Flag = False
break
if Flag:
prompt_Del_ID_None()
return
# 删除成功
prompt_Del()
# 将删除后的信息写入文件
save_excel(self.all_employee_list)
self.show_all()
# 3.修改员工信息,根据符合条件的工号打开修改员工信息的窗口
def Mod_Employee_Info(self):
# 获取输入的信息
number = self.Txt_ID.get()
if not is_ID(number):
prompt_Add_ID()
return
# 用于指示是否打开窗口的指标
Flag = True
for i in self.all_employee_list:
if number in i[0]:
self.Window_Mod_Input()
Flag = False
break
if Flag:
prompt_Del_ID_None()
return
# 3.修改员工信息的主方法
def Mod_Employee_Info_1(self):
# 获取输入的信息
number = self.Txt_ID.get()
names = self.Txt_Name.get()
gender = self.sex.get()
age = self.Txt_Age.get()
department = self.Txt_Department.get()
position = self.Txt_position.get()
mobile = self.Txt_Telephone.get()
if not is_ID(number):
prompt_Add_ID()
return
if not is_Age(age):
prompt_Add_Age()
return
# 遍历,修改员工信息
for i in self.all_employee_list:
if number in i[0]:
i[1] = names
i[2] = gender
i[3] = age
i[4] = department
i[5] = position
i[6] = mobile
# 修改成功
prompt_Mod()
# 将修改后的信息写入文件
save_excel(self.all_employee_list)
self.show_all()
# 4.查找员工信息的主方法
def Search_Employee_Info(self):
# 获取输入的信息
number = self.Txt_ID.get()
names = self.Txt_Name.get()
age = self.Txt_Age.get()
department = self.Txt_Department.get()
position = self.Txt_position.get()
mobile = self.Txt_Telephone.get()
if len(number) != 0 and not is_ID(number):
prompt_Add_ID()
return
if len(age) != 0 and not is_Age(age):
prompt_Add_Age()
return
# 创建临时列表
List = []
# 用来指示是否查找到员工的信息指标
Flag = False
List.append(number.strip())
List.append(names.strip())
List.append(age.strip())
List.append(department.strip())
List.append(position.strip())
List.append(mobile.strip())
# 遍历,根据输入的部分信息找到符合条件的员工
for item in self.all_employee_list:
# and后面加“\”,代表行续符,用于告诉Python解释器,当前行代码未完,下一行也是这个代码的一部分
if (List[0] in item[0] or len(List[0])==0)and \
(List[1] in item[1] or len(List[1])==0)and \
(List[2] in item[3] or len(List[2])==0)and \
(List[3] in item[4] or len(List[3])==0)and \
(List[4] in item[5] or len(List[4])==0)and \
(List[5] in item[6] or len(List[5])==0)and \
(len(List[0])!=0 or len(List[1])!=0 or len(List[2])!=0 or len(List[3])!=0 or len(List[4])!=0 or len(List[5])!=0):
# 满足条件的员工
self.query_result_list.append(item)
if len(List) != 0:
Flag = True
# 把结果加载到TreeView中
self.clear_Tree()
self.add_treeview(self.query_result_list)
# “汇总”统计输出
self.total_text.delete(1.0, tk.END)
self.total_text.insert(tk.END, len(self.Tree.get_children()))
self.query_result_list.clear()
# 是否查找成功
if Flag:
prompt_Search()
else:
prompt_Search_None()
# 添加员工信息的窗口
def Window_Add(self):
add_window = tk.Toplevel(self.window)
add_window.title("添加员工信息")
# 设置窗口居中
window_width = 500
window_height = 500
screen_width = add_window.winfo_screenwidth()
screen_height = add_window.winfo_screenheight()
x = (screen_width - window_width) / 2
y = (screen_height - window_height) / 2
add_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
add_window.resizable(width=False, height=False)
self.Txt_ID = tk.StringVar()
self.Txt_ID.set("")
Label1 = tk.Label(add_window, text = "工号 (6位数字):", font = ('黑体', 12), width = 15)
Label1.place(x = 75, y = 50, anchor = 'nw')
Entry_Line1 = tk.Entry(add_window, show = None, font = ('黑体', 15), textvariable = self.Txt_ID, width = 20)
Entry_Line1.place(x = 200, y = 50, anchor = 'nw')
self.Txt_Name = tk.StringVar()
self.Txt_Name.set("")
Label2 = tk.Label(add_window, text = "姓 名:", font = ('黑体', 12), width = 15)
Label2.place(x = 75, y = 100, anchor = 'nw')
Entry_Line2 = tk.Entry(add_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Name, width = 20)
Entry_Line2.place(x = 200, y = 100, anchor = 'nw')
self.sex = tk.StringVar()
self.sex.set("男")
Label7 = tk.Label(add_window, text = "性 别:", font = ('黑体', 12), width = 15)
Label7.place(x = 75, y = 150, anchor = 'nw')
sex_input1 = tk.Radiobutton(add_window, text="男", variable=self.sex, value="男")
sex_input2 = tk.Radiobutton(add_window, text="女", variable=self.sex, value="女")
sex_input1.place(x = 200, y = 150, anchor = 'nw')
sex_input2.place(x = 260, y = 150, anchor = 'nw')
self.Txt_Age = tk.StringVar()
self.Txt_Age.set("")
Label4 = tk.Label(add_window, text = "年 龄 (数字):", font = ('黑体', 12), width = 15)
Label4.place(x = 75, y = 200, anchor = 'nw')
Entry_Line4 = tk.Entry(add_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Age, width = 20)
Entry_Line4.place(x = 200, y = 200, anchor = 'nw')
self.Txt_Department = tk.StringVar()
self.Txt_Department.set("")
Label3 = tk.Label(add_window, text = "部 门:", font = ('黑体', 12), width = 15)
Label3.place(x = 75, y = 250, anchor = 'nw')
Entry_Line3 = tk.Entry(add_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Department, width = 20)
Entry_Line3.place(x = 200, y = 250, anchor = 'nw')
self.Txt_position = tk.StringVar()
self.Txt_position.set("")
Label5 = tk.Label(add_window, text = "职 务:", font = ('黑体', 12), width = 15)
Label5.place(x = 75, y = 300, anchor = 'nw')
Entry_Line5 = tk.Entry(add_window, show = None, font = ('黑体', 15), textvariable = self.Txt_position, width = 20)
Entry_Line5.place(x = 200, y = 300, anchor = 'nw')
self.Txt_Telephone = tk.StringVar()
self.Txt_Telephone.set("")
Label6 = tk.Label(add_window, text = "手 机 号 码:", font = ('黑体', 12), width = 15)
Label6.place(x = 75, y = 350, anchor = 'nw')
Entry_Line6 = tk.Entry(add_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Telephone, width = 20)
Entry_Line6.place(x = 200, y = 350, anchor = 'nw')
# 定义"确认"组件,此处绑定函数Add_Employee_Info用于添加员工信息
Button1_Yes = tk.Button(add_window, text = '确认', bg = 'silver', font = ('黑体', 12), command = self.Add_Employee_Info, width = 10)
Button1_Yes.place(x = 75, y = 400, anchor = 'nw')
# 定义"取消"组件,此处绑定函数destroy()用于关闭窗口
Button2_No = tk.Button(add_window, text = '取消', bg = 'silver', font = ('黑体', 12), command = lambda:add_window.destroy(), width = 10)
Button2_No.place(x = 325, y = 400, anchor = 'nw')
# 窗口显示
add_window.mainloop()
# 删除员工信息的窗口
def Window_Del(self):
# 创建window的子窗口
del_window = tk.Toplevel(self.window)
del_window.title("删除员工信息")
# 设置窗口居中
window_width = 500
window_height = 300
screen_width = del_window.winfo_screenwidth()
screen_height = del_window.winfo_screenheight()
x = (screen_width - window_width) / 2
y = (screen_height - window_height) / 2
del_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
del_window.resizable(width=False, height=False)
self.Txt_ID = tk.StringVar()
self.Txt_ID.set("")
Label1 = tk.Label(del_window, text = "工号 (6位数字):", font = ('黑体', 12), width = 15)
Label1.place(x = 75, y = 100, anchor = 'nw')
Entry_Line1 = tk.Entry(del_window, show = None, font = ('黑体', 15), textvariable = self.Txt_ID, width = 20)
Entry_Line1.place(x = 200, y = 100, anchor = 'nw')
# 定义"确认"组件,此处绑定函数Del_Employee_Info用于删除员工信息
Button1_Yes = tk.Button(del_window, text = '确认', bg = 'silver', font = ('黑体', 12), command=self.Del_Employee_Info, width = 10)
Button1_Yes.place(x = 75, y = 200, anchor = 'nw')
# 定义"取消"组件,此处绑定函数destroy()用于关闭窗口
Button2_No = tk.Button(del_window, text = '取消', bg = 'silver', font = ('黑体', 12), command = lambda:del_window.destroy(), width = 10)
Button2_No.place(x = 325, y = 200, anchor = 'nw')
# tk.StringVar()用于接收用户输入
result = tk.StringVar()
result.set(">>>请输入待删除员工的工号<<<")
# 在界面中显示文本框,打印result的信息
Show_result = tk.Label(del_window, bg = "white", fg = "black", font = ("黑体", 12), bd = '0', anchor = 'center', textvariable = result)
Show_result.place(x = "50", y = "30", width = "400", height = "50")
# 显示窗口
del_window.mainloop()
# 修改员工信息的窗口
def Window_Mod(self):
# 创建window的子窗口
modify_window = tk.Toplevel(self.window)
modify_window.title("修改员工信息")
# 设置窗口居中
window_width = 500
window_height = 300
screen_width = modify_window.winfo_screenwidth()
screen_height = modify_window.winfo_screenheight()
x = (screen_width - window_width) / 2
y = (screen_height - window_height) / 2
modify_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
modify_window.resizable(width=False, height=False)
self.Txt_ID = tk.StringVar()
self.Txt_ID.set("")
Label1 = tk.Label(modify_window, text = "工号 (6位数字):", font = ('黑体', 12), width = 15)
Label1.place(x = 75, y = 100, anchor = 'nw')
Entry_Line1 = tk.Entry(modify_window, show = None, font = ('黑体', 15), textvariable = self.Txt_ID, width = 20)
Entry_Line1.place(x = 200, y = 100, anchor = 'nw')
# 定义"确认"组件,此处绑定函数Mod_Employee_Info用于修改员工信息
Button1_Yes = tk.Button(modify_window, text = '确认', bg = 'silver', font = ('黑体', 12), command=self.Mod_Employee_Info, width = 10)
Button1_Yes.place(x = 75, y = 200, anchor = 'nw')
# 定义"取消"组件,此处绑定函数destroy()用于关闭窗口
Button2_No = tk.Button(modify_window, text = '取消', bg = 'silver', font = ('黑体', 12), command = lambda:modify_window.destroy(), width = 10)
Button2_No.place(x = 325, y = 200, anchor = 'nw')
# 在界面中显示文本框,打印result的信息
result = tk.StringVar()
result.set(">>>请输入待修改员工的工号<<<")
Show_result = tk.Label(modify_window, bg = "white", fg = "black", font = ("黑体", 12), bd = '0', anchor = 'center', textvariable = result)
Show_result.place(x = "50", y = "30", width = "400", height = "50")
#显示窗口
modify_window.mainloop()
# 输入修改员工信息的窗口
def Window_Mod_Input(self):
# 创建window的子窗口
modify_input_window = tk.Toplevel(self.window)
modify_input_window.title("修改员工信息")
# 设置窗口居中
window_width = 500
window_height = 520
screen_width = modify_input_window.winfo_screenwidth()
screen_height = modify_input_window.winfo_screenheight()
x = (screen_width - window_width) / 2
y = (screen_height - window_height) / 2
modify_input_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
modify_input_window.resizable(width=False, height=False)
# 获取工号信息
number = self.Txt_ID.get()
for i in self.all_employee_list:
if number in i[0]:
Name = i[1]
Sex = i[2]
Age = i[3]
Major = i[4]
Class = i[5]
Telephone = i[6]
# 在用户输入任意值时,设置默认值为相应的工号,不可改变
def on_key_release(event):
if event.widget.get():
event.widget.delete(0, tk.END)
event.widget.insert(0, number)
self.Txt_ID = tk.StringVar()
self.Txt_ID.set(number)
Label1 = tk.Label(modify_input_window, text = "工号 (不可修改):", font = ('黑体', 12), width = 20)
Label1.place(x = 55, y = 100, anchor = 'nw')
Entry_Line1 = tk.Entry(modify_input_window, show = None, font = ('黑体', 15), textvariable = self.Txt_ID, width = 20)
Entry_Line1.place(x = 210, y = 100, anchor = 'nw')
# 使用bind绑定到<KeyRelease>事件
Entry_Line1.bind('<KeyRelease>', on_key_release)
self.Txt_Name = tk.StringVar()
self.Txt_Name.set(Name)
Label2 = tk.Label(modify_input_window, text = "姓 名:", font = ('黑体', 12), width = 20)
Label2.place(x = 55, y = 150, anchor = 'nw')
Entry_Line2 = tk.Entry(modify_input_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Name, width = 20)
Entry_Line2.place(x = 210, y = 150, anchor = 'nw')
self.sex = tk.StringVar()
self.sex.set(Sex)
Label7 = tk.Label(modify_input_window, text = "性 别:", font = ('黑体', 12), width = 20)
Label7.place(x = 55, y = 200, anchor = 'nw')
sex_input1 = tk.Radiobutton(modify_input_window, text="男", variable=self.sex, value="男")
sex_input2 = tk.Radiobutton(modify_input_window, text="女", variable=self.sex, value="女")
sex_input1.place(x = 210, y = 200, anchor = 'nw')
sex_input2.place(x = 270, y = 200, anchor = 'nw')
self.Txt_Age = tk.StringVar()
self.Txt_Age.set(Age)
Label4 = tk.Label(modify_input_window, text = "年 龄 (数字):", font = ('黑体', 12), width = 20)
Label4.place(x = 55, y = 250, anchor = 'nw')
Entry_Line4 = tk.Entry(modify_input_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Age, width = 20)
Entry_Line4.place(x = 210, y = 250, anchor = 'nw')
self.Txt_Department = tk.StringVar()
self.Txt_Department.set(Major)
Label3 = tk.Label(modify_input_window, text = "部 门:", font = ('黑体', 12), width = 20)
Label3.place(x = 55, y = 300, anchor = 'nw')
Entry_Line3 = tk.Entry(modify_input_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Department, width = 20)
Entry_Line3.place(x = 210, y = 300, anchor = 'nw')
self.Txt_position = tk.StringVar()
self.Txt_position.set(Class)
Label5 = tk.Label(modify_input_window, text = "职 务:", font = ('黑体', 12), width = 20)
Label5.place(x = 55, y = 350, anchor = 'nw')
Entry_Line5 = tk.Entry(modify_input_window, show = None, font = ('黑体', 15), textvariable = self.Txt_position, width = 20)
Entry_Line5.place(x = 210, y = 350, anchor = 'nw')
self.Txt_Telephone = tk.StringVar()
self.Txt_Telephone.set(Telephone)
Label6 = tk.Label(modify_input_window, text = "手 机 号 码:", font = ('黑体', 12), width = 20)
Label6.place(x = 55, y = 400, anchor = 'nw')
Entry_Line6 = tk.Entry(modify_input_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Telephone, width = 20)
Entry_Line6.place(x = 210, y = 400, anchor = 'nw')
# 定义"确认"组件,此处绑定函数Mod_Employee_Info_1用于修改员工信息
Button1_Yes = tk.Button(modify_input_window, text = '确认', bg = 'silver', font = ('黑体', 12), command=self.Mod_Employee_Info_1, width = 10)
Button1_Yes.place(x = 55, y = 450, anchor = 'nw')
# 定义"取消"组件,此处绑定函数destroy()用于关闭窗口
Button2_No = tk.Button(modify_input_window, text = '取消', bg = 'silver', font = ('黑体', 12), command = lambda:modify_input_window.destroy(), width = 10)
Button2_No.place(x = 325, y = 450, anchor = 'nw')
# 在界面中显示文本框,打印result的信息
result = tk.StringVar()
result.set(">>>请输入修改后的信息<<<")
Show_result = tk.Label(modify_input_window, bg = "white", fg = "black", font = ("黑体", 12), bd = '0', anchor = 'center', textvariable = result)
Show_result.place(x = "50", y = "30", width = "400", height = "50")
# 显示窗口
modify_input_window.mainloop()
# 查找员工信息的窗口
def Window_Ser(self):
# 创建window的子窗口
search_window = tk.Toplevel(self.window)
search_window.title("查询员工信息")
# 设置窗口居中
window_width = 500
window_height = 500
screen_width = search_window.winfo_screenwidth()
screen_height = search_window.winfo_screenheight()
x = (screen_width - window_width) / 2
y = (screen_height - window_height) / 2
search_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
search_window.resizable(width=False, height=False)
self.Txt_ID = tk.StringVar()
self.Txt_ID.set("")
Label1 = tk.Label(search_window, text = "工号 (6位数字):", font = ('黑体', 12), width = 15)
Label1.place(x = 75, y = 100, anchor = 'nw')
Entry_Line1 = tk.Entry(search_window, show = None, font = ('黑体', 15), textvariable = self.Txt_ID, width = 20)
Entry_Line1.place(x = 200, y = 100, anchor = 'nw')
self.Txt_Name = tk.StringVar()
self.Txt_Name.set("")
Label2 = tk.Label(search_window, text = "姓 名:", font = ('黑体', 12), width = 15)
Label2.place(x = 75, y = 150, anchor = 'nw')
Entry_Line2 = tk.Entry(search_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Name, width = 20)
Entry_Line2.place(x = 200, y = 150, anchor = 'nw')
self.Txt_Age = tk.StringVar()
self.Txt_Age.set("")
Label4 = tk.Label(search_window, text = "年 龄 (数字):", font = ('黑体', 12), width = 15)
Label4.place(x = 75, y = 200, anchor = 'nw')
Entry_Line4 = tk.Entry(search_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Age, width = 20)
Entry_Line4.place(x = 200, y = 200, anchor = 'nw')
self.Txt_Department = tk.StringVar()
self.Txt_Department.set("")
Label3 = tk.Label(search_window, text = "部 门:", font = ('黑体', 12), width = 15)
Label3.place(x = 75, y = 250, anchor = 'nw')
Entry_Line3 = tk.Entry(search_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Department, width = 20)
Entry_Line3.place(x = 200, y = 250, anchor = 'nw')
self.Txt_position = tk.StringVar()
self.Txt_position.set("")
Label5 = tk.Label(search_window, text = "职 务:", font = ('黑体', 12), width = 15)
Label5.place(x = 75, y = 300, anchor = 'nw')
Entry_Line5 = tk.Entry(search_window, show = None, font = ('黑体', 15), textvariable = self.Txt_position, width = 20)
Entry_Line5.place(x = 200, y = 300, anchor = 'nw')
self.Txt_Telephone = tk.StringVar()
self.Txt_Telephone.set("")
Label6 = tk.Label(search_window, text = "手 机 号 码:", font = ('黑体', 12), width = 15)
Label6.place(x = 75, y = 350, anchor = 'nw')
Entry_Line6 = tk.Entry(search_window, show = None, font = ('黑体', 15), textvariable = self.Txt_Telephone, width = 20)
Entry_Line6.place(x = 200, y = 350, anchor = 'nw')
# 定义"确认"组件,此处绑定函数Search_Employee_Info用于修改员工信息
Button1_Yes = tk.Button(search_window, text = '确认', bg = 'silver', font = ('黑体', 12), command = self.Search_Employee_Info, width = 10)
Button1_Yes.place(x = 75, y = 400, anchor = 'nw')
# 定义"取消"组件,此处绑定函数destroy()用于关闭窗口
Button2_No = tk.Button(search_window, text = '取消', bg = 'silver', font = ('黑体', 12), command = lambda:search_window.destroy(), width = 10)
Button2_No.place(x = 325, y = 400, anchor = 'nw')
# 在界面中显示文本框,打印result的信息
result = tk.StringVar()
result.set(">>>请输入待查找员工的部分信息(可不全填)<<<")
Show_result = tk.Label(search_window, bg = "white", fg = "black", font = ("黑体", 12), bd = '0', anchor = 'center', textvariable = result)
Show_result.place(x = "50", y = "30", width = "400", height = "50")
# 显示窗口
search_window.mainloop()
# 退出管理系统的窗口
def Window_Exit(self):
# 创建app的子窗口
exit_window = tk.Toplevel()
exit_window.title("退出管理系统")
# 设置窗口居中
window_width = 400
window_height = 300
screen_width = exit_window.winfo_screenwidth()
screen_height = exit_window.winfo_screenheight()
x = (screen_width - window_width) / 2
y = (screen_height - window_height) / 2
exit_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
exit_window.resizable(width=False, height=False)
# 定义"确认"组件,此处绑定函数destroy()用于关闭主窗口
Button1_Yes = tk.Button(exit_window, text = '确认', bg = 'silver', font = ('黑体', 12), command = lambda:self.window.destroy(), width = 10)
Button1_Yes.place(x = 50, y = 200, anchor = 'nw')
# 定义"取消"组件,此处绑定函数destroy()用于关闭窗口
Button2_No = tk.Button(exit_window, text = '取消', bg = 'silver', font = ('黑体', 12), command = lambda:exit_window.destroy(), width = 10)
Button2_No.place(x = 250, y = 200, anchor = 'nw')
# 在界面中显示文本框,打印result的信息
result = tk.StringVar()
result.set(">>>您确认离开系统吗?<<<")
Show_result = tk.Label(exit_window, bg = "white", fg = "black", font = ("黑体", 15), bd = '0', anchor = 'center', textvariable = result)
Show_result.place(x = "50", y = "75", width = "300", height = "50")
# 显示窗口
exit_window.mainloop()
# 创建程序介绍页面
def program_about(self):
about = tk.Toplevel()
about.title('关于程序')
# 设置窗口居中
window_width = 450
window_height = 400
screen_width = about.winfo_screenwidth()
screen_height = about.winfo_screenheight()
x = (screen_width - window_width) / 2
y = (screen_height - window_height) / 2
about.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
about.resizable(width=False, height=False)
about_frame = tk.Frame(about, width=400, height=380)
about_frame.pack()
about_font_1 = tkFont.Font(family='宋体', size=13)
tk.Label(about_frame, text='员工信息管理系统', font=about_font_1).place(x=120, y=20)
tk.Label(about_frame, text='使用编程语言:Python', font=about_font_1).place(x=25, y=90)
tk.Label(about_frame, text='保存信息方式:工作目录下自动创建Excel文件', font=about_font_1).place(x=25, y=150)
tk.Label(about_frame, text='Excel文件:文件名称employee.xlsx', font=about_font_1).place(x=25, y=210)
tk.Label(about_frame, text='修改员工信息:在员工信息列表直接双击鼠标', font=about_font_1).place(x=25, y=270)
tk.Label(about_frame, text='创作者:www.pyhint.com', font=about_font_1).place(x=25, y=330)
about.mainloop()
# 程序讲解页面
def help_window(self):
webbrowser.open("https://www.pyhint.com/article/153.html")
# 显示所有员工信息
def show_all(self):
self.clear_Tree()
# 把所有条件文本框清空
self.get_number.delete(0, tk.END)
self.get_name.delete(0, tk.END)
self.get_department.delete(0, tk.END)
self.get_position.delete(0, tk.END)
self.add_treeview(self.all_employee_list)
# “汇总”统计输出
self.total_text.delete(1.0, tk.END)
self.total_text.insert(tk.END, len(self.Tree.get_children()))
# 遍历列表数据到Treeview控件中
def add_treeview(self,current_list):
for index in range(len(current_list)):
self.Tree.insert("", index, values=(current_list[index][0],
current_list[index][1],
current_list[index][2],
current_list[index][3],
current_list[index][4],
current_list[index][5],
current_list[index][6]))
# 根据输入的内容,查询指定员工信息
def search_result(self):
result_message = []
result_message.append(self.get_number.get().strip())
result_message.append(self.get_name.get().strip())
result_message.append(self.get_department.get().strip())
result_message.append(self.get_position.get().strip())
# 遍历,根据输入的部分信息找到符合条件的员工
for item in self.all_employee_list:
# and后面加“\”,代表行续符,用于告诉Python解释器,当前行代码未完,下一行也是这个代码的一部分
if (result_message[0] in item[0] or len(result_message[0])==0)and \
(result_message[1] in item[1] or len(result_message[1])==0)and \
(result_message[2] in item[4] or len(result_message[2])==0)and \
(result_message[3] in item[5] or len(result_message[3])==0)and \
(len(result_message[0])!=0 or len(result_message[1])!=0 or len(result_message[2])!=0 or len(result_message[3])!=0):
# 满足条件的员工
self.query_result_list.append(item)
# 把结果加载的TreeView中
self.clear_Tree()
self.add_treeview(self.query_result_list)
# “汇总”统计输出
self.total_text.delete(1.0, tk.END)
self.total_text.insert(tk.END, len(self.Tree.get_children()))
self.query_result_list.clear()
# 定义函数,清空Treeview控件中的全部内容
def clear_Tree(self):
for i in self.Tree.get_children():
self.Tree.delete(i)
# “汇总”统计输出
self.total_text.delete(1.0, tk.END)
self.total_text.insert(tk.END, 0)
# 定义员工信息管理系统主页面控件
def main(self):
# 设定Style
self.Style01 = Style()
self.Style01.configure("TPanedwindow", background="#f0f0f0")
self.Style01.configure("TButton", width=15, font=('宋体', 16,))
# 上边是标题部分
self.Pane_top = PanedWindow(width=980, height=85, style="TPanedwindow")
self.Pane_top.place(x=10, y=5)
tk.Label(self.Pane_top, text="员工信息管理系统", bg='#f0f0f0', font=("宋体", 40), width=30).place(x=60, y=10)
# 在主界面创建“汇总”信息,显示员工信息的数量
total_label = tk.Label(self.Pane_top, text='汇总:', font=10)
total_label.place(x=790, y=58, width=50, height=25)
self.total_text = tk.Text(self.Pane_top, relief=tk.FLAT, bg='#f0f0f0', font=10)
self.total_text.place(x=840, y=60, width=50, height=25)
# 左边是按钮区域,创建一个容器
self.Pane_left = PanedWindow(width=195, height=500, style="TPanedwindow")
self.Pane_left.place(x=5, y=95)
self.Pane_right = PanedWindow(width=780, height=500, style="TPanedwindow")
self.Pane_right.place(x=210, y=95)
# 添加左边按钮
Button(self.Pane_left, text="添加员工信息", style="TButton", command = self.Window_Add).place(x=20, y=10)
Button(self.Pane_left, text="删除员工信息", style="TButton", command = self.Window_Del).place(x=20, y=70)
Button(self.Pane_left, text="修改员工信息", style="TButton", command = self.Window_Mod).place(x=20, y=130)
Button(self.Pane_left, text="查询员工信息", style="TButton", command = self.Window_Ser).place(x=20, y=190)
Button(self.Pane_left, text="显示所有信息", style="TButton", command = self.show_all).place(x=20, y=250)
Button(self.Pane_left, text="关于程序信息", style="TButton", command = self.program_about).place(x=20, y=310)
Button(self.Pane_left, text="程序讲解页面", style="TButton", command = self.help_window).place(x=20, y=370)
Button(self.Pane_left, text="退出管理系统", style="TButton", command = self.Window_Exit).place(x=20, y=430)
# 添加简易的员工信息查询框架
self.LabelFrame_query = tk.LabelFrame(self.Pane_right, text="员工信息查询", width=770, height=50)
self.LabelFrame_query.place(x=5, y=5)
# 添加控件
self.Label_number = tk.Label(self.LabelFrame_query, text="工号:")
self.Label_number.place(x=5, y=5)
self.get_number = tk.Entry(self.LabelFrame_query, width=12)
self.get_number.place(x=40, y=5)
self.Label_name = tk.Label(self.LabelFrame_query, text="姓名:")
self.Label_name.place(x=125, y=5)
self.get_name = tk.Entry(self.LabelFrame_query, width=12)
self.get_name.place(x=160, y=5)
self.Label_department = tk.Label(self.LabelFrame_query, text="部门:")
self.Label_department.place(x=245, y=5)
self.get_department = tk.Entry(self.LabelFrame_query, width=14)
self.get_department.place(x=280, y=5)
self.Label_position = tk.Label(self.LabelFrame_query, text="职务:")
self.Label_position.place(x=380, y=5)
self.get_position = tk.Entry(self.LabelFrame_query, width=14)
self.get_position.place(x=415, y=5)
self.search_Button = tk.Button(self.LabelFrame_query, text="查询", width=4,command=self.search_result)
self.search_Button.place(x=520, y=-4)
self.clear_Button = tk.Button(self.LabelFrame_query, text="清除", width=4, command=self.del_Entry_content)
self.clear_Button.place(x=560, y=-4)
self.clear_all = tk.Button(self.LabelFrame_query, text="清空全部", width=8, command=self.clear_Tree)
self.clear_all.place(x=625, y=-4)
self.show_all_Button = tk.Button(self.LabelFrame_query, text="显示全部", width=8,command=self.show_all)
self.show_all_Button.place(x=695, y=-4)
# 添加TreeView控件
self.Tree = Treeview(self.Pane_right, columns=("number", "names", "gender", "age",
"department", "position", "mobile"),
show="headings", height=19)
# 设置每一个列的宽度和对齐的方式
self.Tree.column("number", width=100, anchor="center")
self.Tree.column("names", width=100, anchor="center")
self.Tree.column("gender", width=50, anchor="center")
self.Tree.column("age", width=50, anchor="center")
self.Tree.column("department", width=150, anchor="center")
self.Tree.column("position", width=150, anchor="center")
self.Tree.column("mobile", width=150, anchor="center")
# 设置每个列的标题
self.Tree.heading("number", text="工号")
self.Tree.heading("names", text="姓名")
self.Tree.heading("gender", text="性别")
self.Tree.heading("age", text="年龄")
self.Tree.heading("department", text="部门")
self.Tree.heading("position", text="职务")
self.Tree.heading("mobile", text="手机号码")
self.Tree.place(x=5, y=60)
# 创建滚动条
scrollbar = ttk.Scrollbar(self.Pane_right, orient="vertical", command=self.Tree.yview)
scrollbar.place(x=760, y=60, relheight=0.8)
# 将滚动条控件与Treeview控件关联
self.Tree.config(yscrollcommand=scrollbar.set)
# 鼠标双击员工信息列表任意一行,可以触发修改员工信息页面
def on_double_click(event):
# 获取被双击的项的IID
iid = self.Tree.focus()
if iid == '':
return # 如果没有选中任何一行,则直接返回
# 获取该行的所有值,结果为元组,再将元组转换成列表,最后获取列表的第一个值
values = self.Tree.item(iid, "values")
values_list = list(values)
result_list = values_list[0]
num = int(result_list)
self.Txt_ID = tk.StringVar()
self.Txt_ID.set(num)
Entry_Line1 = tk.Entry(self.window, show = None, font = ('黑体', 15), textvariable = self.Txt_ID, width = 20)
Entry_Line1.place()
self.Mod_Employee_Info()
# 绑定双击事件
self.Tree.bind("<Double-1>", on_double_click)
# 当前模块直接被执行
if __name__ == '__main__':
# 创建主窗口
root = tk.Tk()
Root(root)
# 开启主循环,让窗口处于显示状态
root.mainloop()