from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from jsonutil import BaseJson
from excel_util import ExcelUtil
from tkinter.filedialog import *
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plot
import pandas
class ManageWin:
# 构造方法 初始化
def __init__(self):
# 初始化窗体
win = Tk()
self.root = win # 保存实例的属性
win.title("后台管理界面")
win.geometry('500x300+500+100')
# 初始化菜单
self.createMenu()
# 初始化欢迎界面
# self.createWelcome()
self.initFrame()
win.mainloop() # 阻塞
# 初始化Frame 把所有的Frame 创建出来
def initFrame(self):
self.welcomeFrame = WelcomeFrame(self.root)
self.listFrame = ListFrame(self.root,self)
self.aboutFrame = AboutFrame(self.root)
self.dataFrame = DataFrame(self.root)
self.addFrame = AddFrame(self.root,self)#=======================
self.createWelcome()
# 初始化菜单
def createMenu(self):
menuBar = Menu() # 菜单栏
menuBar.add_command(label='图书管理',command=self.showListFrame)
menuBar.add_command(label='数据分析',command=self.showDataFrame)
# menuBar.add_command(label='导入导出')
helpMenu = Menu(tearoff=False)
helpMenu.add_command(label='关于我们',command=self.showAboutFrame)
helpMenu.add_command(label='退出系统',command=self.quit)
menuBar.add_cascade(label='帮助',menu=helpMenu)
# 创建子菜单
exportMenu = Menu(tearoff=False) # tearoff=False 隐藏虚线
exportMenu.add_command(label='导入',command=self.inport)
exportMenu.add_separator() # 添加分隔线
exportMenu.add_command(label='导出',command=self.export)
# 添加到菜单栏中
menuBar.add_cascade(label='导入导出',menu=exportMenu)
# self.root['menu'] = menuBar
self.root.configure(menu=menuBar) # 把菜单添加到窗口中
## 先读入excel --- 合并到 list ---再写出到json文件
def inport(self):
# 打开文件选择器 导入
filepath = askopenfile(title='打开文件', filetypes=[('Excel文件', '.xlsx')])
if filepath==None: # 如果取消了选择
return;
print(">>>>>>选择的:",filepath)
# 读取Excel 中数据,并转为 字典格式
excelData = ExcelUtil.readDict(filepath.name)
# 再获取原有的json文件中的数据
# data = self.listFrame.data_dict_list
data = BaseJson.readJson('books.json')
# 合并 excel中读入的数据和原有 json 中读入的数据
data.extend(excelData)
# 把合并后的数据写出到 books.json 文件中
BaseJson.saveToJson(data,'books.json')
#
def export(self):
# 打开文件选择器 导出
filepath = asksaveasfile(title='保存文件', filetypes=[('Excel文件', '.xlsx')])
if filepath==None: # 如果取消了选择
return;
fliename = filepath.name;
if fliename.endswith('xlsx')==False and fliename.endswith('xls')==False:
fliename = fliename+'.xlsx';
print("导出的文件名:",fliename)
# 读取数据
data = BaseJson.readJson("books.json")
ExcelUtil.listToExcel(data,fliename)
messagebox.showinfo(title="提示信息",message="导出完成!")
# 退出系统
def quit(self):
sel = messagebox.askyesno(title='提示信息',message='您确定退出系统么?')
if sel == True:
self.root.destroy()
# 初始化欢迎界面
def createWelcome(self):
self.cur_frame = self.welcomeFrame
self.cur_frame.pack()
# 显示列表界面 当点击管理菜单时,调用这里
def showListFrame(self):
self.showFrame(self.listFrame)
def showDataFrame(self):
self.showFrame(self.dataFrame)
def showAboutFrame(self):
self.showFrame(self.aboutFrame)
def showAddFrame(self):
self.showFrame(self.addFrame)
# 切换界面 ===========统一公共的方法========
def showFrame(self,frame):
self.cur_frame.pack_forget()
self.cur_frame = frame # 当前正在显示的界面
self.cur_frame.pack() # 显示现在的当前的界面
# 欢迎界面类
class WelcomeFrame(Frame): # 继承
def __init__(self,win):
super().__init__(win)
Label(self,text='欢迎使用图书管理系统',foreground='red',font=('黑体',30,'bold')).pack(pady=60,ipady=30)
class AboutFrame(Frame):
def __init__(self,win):
super().__init__(win)
Label(self, text='版本:V1.0.0.0.1', foreground='red', font=('黑体', 20, 'bold')).pack(pady=6, ipady=10)
Label(self, text='版权所有:***团队', foreground='red', font=('黑体', 20, 'bold')).pack(pady=6, ipady=10)
Label(self, text='小组成员:张衡;曹操', foreground='red', font=('黑体', 20, 'bold')).pack(pady=6, ipady=10)
class DataFrame(Frame):
def __init__(self,win):
super().__init__(win)
Label(self, text='数据分析界面', foreground='blue', font=('黑体', 30, 'bold')).pack(pady=10, ipady=30)
Button(self,text='出版社发行数量统计',command=self.showPie).pack(ipadx=10)
# 显示饼图
def showPie(self):
data = BaseJson.readJson('books.json')
# print(data)
dataFrame = pandas.DataFrame(data)
v = dataFrame.groupby(['pubcom']).count() # 按出版社分组统计
keys = list(v.get('bookname').keys())
vals = v.get('bookname').values
plot.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
plot.rcParams['axes.unicode_minus'] = False # 步骤二(解决坐标轴负数的负号显示问题)
# # 开始生成饼图
# plot.title('出版社图书数量统计')
# plot.pie(vals,autopct='%.1f%%',labels=keys)
# plot.show()
# 创建饼图
# print("))))==",plot.subplots())
fig, ax = plot.subplots()
ax.pie(vals, autopct='%.1f%%', labels=keys)
# 初始化Tk界面
root = Tk()
root.title("出版社图书数量统计")
# 将饼图嵌入Tk界面
fig_canvas = FigureCanvasTkAgg(fig, master=root)
fig_canvas.draw()
fig_canvas.get_tk_widget().pack(side='top', fill='both', expand=1)
# 启动Tk事件循环
root.mainloop()
class ListFrame(Frame):
def __init__(self,win,manage_win):
self.manage_win = manage_win # 保存上一个类 ManageWin 的对象
super().__init__(win)
# Label(self, text='列表界面', foreground='green', font=('黑体', 30, 'bold')).pack(pady=60, ipady=30)
header = ['图书名称', '图书价格', '图书作者', '出版社']
table = ttk.Treeview(self)
self.table = table; #======= 保存到 对象中=======
table.configure(columns=header, show='headings')
for item in header:
table.column(item, width=120, anchor=CENTER)
table.heading(item, text=item)
# 加载数据
self.reload()
table.grid(row=0,column=0,columnspan=3)
#======操作按钮=====
Button(self,text='添加图书',command=self.manage_win.showAddFrame).grid(row=1,pady=20,column=0)
Button(self,text='删除图书',command=self.delRow).grid(row=1,column=1)
Button(self,text='刷新图书',command=self.reload).grid(row=1,column=2)
def reload(self):
self.clearAll()
# 加载数据