保存底部仅将最后一个条目保存到 excel sheet (tkinter)
Save bottom only saves the last entry into excel sheet (tkinter)
这里,我有两个 classes。第一个 (MedicalDevices.py) 具有我想在第二个 class (tkinter_devices.py) 上使用的功能。
我是 python 的新手,非常感谢您的帮助
我面临的问题:
我正在尝试将设备信息输入 excel sheet,但每次我输入多个设备的信息时,它只会保存我在 tkinter 运行 时输入的最后一个条目。
MedicalDevices.py
import datetime
import pandas as pd
# excel file path
f_path = "medical_devices_data.xlsx"
df = pd.read_excel(f_path, sheet_name="Sheet1")
class MedicalDevices:
# class attributes: to keep truck the number of the objects that been made.
num_of_devices = 0
# initialization/ construction
def __init__(self, name, sn, manufacture, model, supplier, department='In Store', warranty_expire="Expired"):
# object attributes (to make private attribute, add __ before the name
self.name = name
self.sn = sn
self.manufacture = manufacture
self.model = model
self.supplier = supplier
self.department = department
self.warranty_expire = warranty_expire
# increase number of devices made with every initialization
MedicalDevices.num_of_devices += 1
# dunder (double underscore)method
# override function to print string instead of printing the memory address of an object
def __str__(self):
return f"Name: {self.name}\nSerial#: {self.sn}\nManufacture: {self.manufacture}\n" \
f"Model: {self.model}\nSupplier: {self.supplier}\nDepartment: {self.department}\n" \
f"Warranty expire on: {self.warranty_expire}"
def add_new_device(newDevice):
SerA = df["Name"]
SerB = df["Serial"]
SerC = df["Manufacture"]
SerD = df["Model"]
SerE = df["Supplier"]
SerF = df["Department"]
SerG = df["Warranty"]
# this must be Series type to be able to concatenate with DataFrame
A = pd.Series(newDevice.name)
B = pd.Series(newDevice.sn)
C = pd.Series(newDevice.manufacture)
D = pd.Series(newDevice.model)
E = pd.Series(newDevice.supplier)
F = pd.Series(newDevice.department)
G = pd.Series(newDevice.warranty_expire)
SerA = SerA.append(A)
SerB = SerB.append(B)
SerC = SerC.append(C)
SerD = SerD.append(D)
SerE = SerE.append(E)
SerF = SerF.append(F)
SerG = SerG.append(G)
df2 = pd.DataFrame({"Name": SerA,
"Serial": SerB,
"Manufacture": SerC,
"Model": SerD,
"Department": SerE,
"Supplier": SerF,
"Warranty": SerG})
df2.to_excel(f_path, index=False)
print(f"A new device added with Serial#: {newDevice.sn}")
#
# def search_by_sn(self, sn):
# if sn in df.values:
# print("Got it. Here is the device(s) info: \n-------------------------------")
# print(df.loc[df.Serial == sn])
# else:
# print("Not found")
# newInput = input("Do you want to add a new device (yes/ no): ")
# if newInput == "yes":
# self.add_new_device(DC_1)
# else:
# print("Ok")
# To check Warranty
def check_warranty(self):
date = datetime.datetime.strptime(self.warranty_expire, '%Y/%m/%d').date()
if date >= datetime.date.today():
print(self.name + " is still in Warranty\n" + "Warranty expires on " + self.warranty_expire)
else:
print("Attention, Warranty expired on " + self.warranty_expire)
tkinter_devices.py
import tkinter as tk
from tkinter import ttk
import pandas as pd
from MedicalDevices import MedicalDevices
font1 = ("Verdana", 12)
font2 = ("Verdana", 10)
pageSize = "500x300"
f_path = "medical_devices_data.xlsx"
df = pd.read_excel(f_path, sheet_name="Sheet1")
class MedicalDeviceApp(tk.Tk):
# args=argument (any number of argument (unlimited))
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Medical Devices Data")
tk.Tk.wm_geometry(self, pageSize) # (width x height)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, AddDevice, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text="Start Page", font=font1)
label.grid(row=0, column=5, sticky="nsew")
bot1 = ttk.Button(self, text="Add a new device",
command=lambda: controller.show_frame(AddDevice))
bot1.grid(row=1, column=0, sticky="nsew", columnspan=1, ipadx=5)
bot2 = ttk.Button(self, text="Page Two",
command=lambda: controller.show_frame(PageTwo))
bot2.grid(row=2, column=0, sticky="nsew")
bot_exit = ttk.Button(self, text="Exit", command=lambda: controller.destroy())
bot_exit.grid(row=3, column=0, sticky="nsew")
class AddDevice(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# Labels
label1 = ttk.Label(self, text="Enter a new device information", font=font1)
label1.grid(row=0, column=1)
label2 = ttk.Label(self, text="Required information with *")
label2.grid(row=1, column=1, pady=5)
label_name = ttk.Label(self, text="Device Name:", font=font2)
label_name.grid(row=2, column=0, sticky="w")
label_serial = ttk.Label(self, text="Serial Number:", font=font2)
label_serial.grid(row=3, column=0, sticky="w")
label_manf = ttk.Label(self, text="Manufacture:", font=font2)
label_manf.grid(row=4, column=0, sticky="w")
label_model = ttk.Label(self, text="Model:", font=font2)
label_model.grid(row=5, column=0, padx=2, sticky="w")
label_supplier = ttk.Label(self, text="Supplier:", font=font2)
label_supplier.grid(row=6, column=0, padx=2, sticky="w")
label_depart = ttk.Label(self, text="Department:", font=font2)
label_depart.grid(row=7, column=0, padx=2, sticky="w")
label_expire = ttk.Label(self, text="Expire Date:", font=font2)
label_expire.grid(row=8, column=0, padx=2, sticky="w")
# Entries
self.entry_name = ttk.Entry(self)
self.entry_name.grid(row=2, column=1, ipadx=20, pady=5)
self.entry_serial = ttk.Entry(self)
self.entry_serial.grid(row=3, column=1, ipadx=20, pady=5)
self.entry_manf = ttk.Entry(self)
self.entry_manf.grid(row=4, column=1, ipadx=20, pady=5)
self.entry_model = ttk.Entry(self)
self.entry_model.grid(row=5, column=1, ipadx=20, pady=5)
self.entry_supplier = ttk.Entry(self)
self.entry_supplier.grid(row=6, column=1, ipadx=20, pady=5)
self.entry_depart = ttk.Entry(self)
self.entry_depart.grid(row=7, column=1, ipadx=20, pady=5)
self.entry_expire = ttk.Entry(self)
self.entry_expire.grid(row=8, column=1, ipadx=20, pady=5)
# Bottoms
self.bot_save = ttk.Button(self, text="Save", command=self.save)
self.bot_save.grid(row=2, column=2, ipadx=20, pady=5, columnspan=1)
self.bot_clear = ttk.Button(self, text="Clear", command=self.delete)
self.bot_clear.grid(row=4, column=2, ipadx=20, pady=2, columnspan=1)
self.bot_back = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
self.bot_back.grid(row=6, column=2, ipadx=20)
self.bot_exit = ttk.Button(self, text="Exit", command=lambda: controller.destroy())
self.bot_exit.grid(row=8, column=2, ipadx=25)
def delete(self):
self.entry_name.delete(0, 'end')
self.entry_serial.delete(0, 'end')
self.entry_manf.delete(0, 'end')
self.entry_model.delete(0, 'end')
self.entry_supplier.delete(0, 'end')
self.entry_depart.delete(0, 'end')
self.entry_expire.delete(0, 'end')
def save(self):
if int(self.entry_serial.get()) in df.values:
print("found it ")
self.delete()
else:
device = MedicalDevices(self.entry_name.get(), self.entry_serial.get(), self.entry_manf.get(),
self.entry_model.get(), self.entry_supplier.get(), self.entry_depart.get(),
self.entry_expire.get())
MedicalDevices.add_new_device(device)
self.delete()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text="Page Tow", font=font1)
label.pack(pady=10, padx=10)
bot1 = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
bot1.pack()
app = MedicalDeviceApp()
app.mainloop()
在 add_new_device()
中,您从全局 df
复制系列并附加新记录,然后使用新系列创建一个新数据帧 df2
并保存到文件。但是您忘记更新全局 df
以使其不包含新设备。下次要添加另一个新设备时,您再次从全局 df
复制系列,其中没有以前添加的设备,附加当前的新设备并保存到文件。然后将在没有先前添加的设备的情况下覆盖该文件。
要解决此问题,您需要更新全局 df
而不是创建新数据框 df2
。还建议将全局 df
作为 class 变量移动到 MedicalDevices
中:
class MedicalDevices:
# excel file path
f_path = "medical_devices_data.xlsx"
df = pd.read_excel(f_path, sheet_name="Sheet1")
...
def add_new_device(newDevice):
# update class dataframe `df` instead of creating new one
MedicalDevices.df = MedicalDevices.df.append({
"Name": newDevice.name,
"Serial": newDevice.sn,
"Manufacture": newDevice.manufacture,
"Model": newDevice.model,
"Supplier": newDevice.supplier,
"Department": newDevice.department,
"Warranty": newDevice.warranty_expire
}, ignore_index=True)
# export to file
MedicalDevices.df.to_excel(MedicalDevices.f_path, index=False)
print(f"A new device added with Serial#: {newDevice.sn}")
这里,我有两个 classes。第一个 (MedicalDevices.py) 具有我想在第二个 class (tkinter_devices.py) 上使用的功能。
我是 python 的新手,非常感谢您的帮助
我面临的问题: 我正在尝试将设备信息输入 excel sheet,但每次我输入多个设备的信息时,它只会保存我在 tkinter 运行 时输入的最后一个条目。
MedicalDevices.py
import datetime
import pandas as pd
# excel file path
f_path = "medical_devices_data.xlsx"
df = pd.read_excel(f_path, sheet_name="Sheet1")
class MedicalDevices:
# class attributes: to keep truck the number of the objects that been made.
num_of_devices = 0
# initialization/ construction
def __init__(self, name, sn, manufacture, model, supplier, department='In Store', warranty_expire="Expired"):
# object attributes (to make private attribute, add __ before the name
self.name = name
self.sn = sn
self.manufacture = manufacture
self.model = model
self.supplier = supplier
self.department = department
self.warranty_expire = warranty_expire
# increase number of devices made with every initialization
MedicalDevices.num_of_devices += 1
# dunder (double underscore)method
# override function to print string instead of printing the memory address of an object
def __str__(self):
return f"Name: {self.name}\nSerial#: {self.sn}\nManufacture: {self.manufacture}\n" \
f"Model: {self.model}\nSupplier: {self.supplier}\nDepartment: {self.department}\n" \
f"Warranty expire on: {self.warranty_expire}"
def add_new_device(newDevice):
SerA = df["Name"]
SerB = df["Serial"]
SerC = df["Manufacture"]
SerD = df["Model"]
SerE = df["Supplier"]
SerF = df["Department"]
SerG = df["Warranty"]
# this must be Series type to be able to concatenate with DataFrame
A = pd.Series(newDevice.name)
B = pd.Series(newDevice.sn)
C = pd.Series(newDevice.manufacture)
D = pd.Series(newDevice.model)
E = pd.Series(newDevice.supplier)
F = pd.Series(newDevice.department)
G = pd.Series(newDevice.warranty_expire)
SerA = SerA.append(A)
SerB = SerB.append(B)
SerC = SerC.append(C)
SerD = SerD.append(D)
SerE = SerE.append(E)
SerF = SerF.append(F)
SerG = SerG.append(G)
df2 = pd.DataFrame({"Name": SerA,
"Serial": SerB,
"Manufacture": SerC,
"Model": SerD,
"Department": SerE,
"Supplier": SerF,
"Warranty": SerG})
df2.to_excel(f_path, index=False)
print(f"A new device added with Serial#: {newDevice.sn}")
#
# def search_by_sn(self, sn):
# if sn in df.values:
# print("Got it. Here is the device(s) info: \n-------------------------------")
# print(df.loc[df.Serial == sn])
# else:
# print("Not found")
# newInput = input("Do you want to add a new device (yes/ no): ")
# if newInput == "yes":
# self.add_new_device(DC_1)
# else:
# print("Ok")
# To check Warranty
def check_warranty(self):
date = datetime.datetime.strptime(self.warranty_expire, '%Y/%m/%d').date()
if date >= datetime.date.today():
print(self.name + " is still in Warranty\n" + "Warranty expires on " + self.warranty_expire)
else:
print("Attention, Warranty expired on " + self.warranty_expire)
tkinter_devices.py
import tkinter as tk
from tkinter import ttk
import pandas as pd
from MedicalDevices import MedicalDevices
font1 = ("Verdana", 12)
font2 = ("Verdana", 10)
pageSize = "500x300"
f_path = "medical_devices_data.xlsx"
df = pd.read_excel(f_path, sheet_name="Sheet1")
class MedicalDeviceApp(tk.Tk):
# args=argument (any number of argument (unlimited))
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Medical Devices Data")
tk.Tk.wm_geometry(self, pageSize) # (width x height)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, AddDevice, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text="Start Page", font=font1)
label.grid(row=0, column=5, sticky="nsew")
bot1 = ttk.Button(self, text="Add a new device",
command=lambda: controller.show_frame(AddDevice))
bot1.grid(row=1, column=0, sticky="nsew", columnspan=1, ipadx=5)
bot2 = ttk.Button(self, text="Page Two",
command=lambda: controller.show_frame(PageTwo))
bot2.grid(row=2, column=0, sticky="nsew")
bot_exit = ttk.Button(self, text="Exit", command=lambda: controller.destroy())
bot_exit.grid(row=3, column=0, sticky="nsew")
class AddDevice(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# Labels
label1 = ttk.Label(self, text="Enter a new device information", font=font1)
label1.grid(row=0, column=1)
label2 = ttk.Label(self, text="Required information with *")
label2.grid(row=1, column=1, pady=5)
label_name = ttk.Label(self, text="Device Name:", font=font2)
label_name.grid(row=2, column=0, sticky="w")
label_serial = ttk.Label(self, text="Serial Number:", font=font2)
label_serial.grid(row=3, column=0, sticky="w")
label_manf = ttk.Label(self, text="Manufacture:", font=font2)
label_manf.grid(row=4, column=0, sticky="w")
label_model = ttk.Label(self, text="Model:", font=font2)
label_model.grid(row=5, column=0, padx=2, sticky="w")
label_supplier = ttk.Label(self, text="Supplier:", font=font2)
label_supplier.grid(row=6, column=0, padx=2, sticky="w")
label_depart = ttk.Label(self, text="Department:", font=font2)
label_depart.grid(row=7, column=0, padx=2, sticky="w")
label_expire = ttk.Label(self, text="Expire Date:", font=font2)
label_expire.grid(row=8, column=0, padx=2, sticky="w")
# Entries
self.entry_name = ttk.Entry(self)
self.entry_name.grid(row=2, column=1, ipadx=20, pady=5)
self.entry_serial = ttk.Entry(self)
self.entry_serial.grid(row=3, column=1, ipadx=20, pady=5)
self.entry_manf = ttk.Entry(self)
self.entry_manf.grid(row=4, column=1, ipadx=20, pady=5)
self.entry_model = ttk.Entry(self)
self.entry_model.grid(row=5, column=1, ipadx=20, pady=5)
self.entry_supplier = ttk.Entry(self)
self.entry_supplier.grid(row=6, column=1, ipadx=20, pady=5)
self.entry_depart = ttk.Entry(self)
self.entry_depart.grid(row=7, column=1, ipadx=20, pady=5)
self.entry_expire = ttk.Entry(self)
self.entry_expire.grid(row=8, column=1, ipadx=20, pady=5)
# Bottoms
self.bot_save = ttk.Button(self, text="Save", command=self.save)
self.bot_save.grid(row=2, column=2, ipadx=20, pady=5, columnspan=1)
self.bot_clear = ttk.Button(self, text="Clear", command=self.delete)
self.bot_clear.grid(row=4, column=2, ipadx=20, pady=2, columnspan=1)
self.bot_back = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
self.bot_back.grid(row=6, column=2, ipadx=20)
self.bot_exit = ttk.Button(self, text="Exit", command=lambda: controller.destroy())
self.bot_exit.grid(row=8, column=2, ipadx=25)
def delete(self):
self.entry_name.delete(0, 'end')
self.entry_serial.delete(0, 'end')
self.entry_manf.delete(0, 'end')
self.entry_model.delete(0, 'end')
self.entry_supplier.delete(0, 'end')
self.entry_depart.delete(0, 'end')
self.entry_expire.delete(0, 'end')
def save(self):
if int(self.entry_serial.get()) in df.values:
print("found it ")
self.delete()
else:
device = MedicalDevices(self.entry_name.get(), self.entry_serial.get(), self.entry_manf.get(),
self.entry_model.get(), self.entry_supplier.get(), self.entry_depart.get(),
self.entry_expire.get())
MedicalDevices.add_new_device(device)
self.delete()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text="Page Tow", font=font1)
label.pack(pady=10, padx=10)
bot1 = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
bot1.pack()
app = MedicalDeviceApp()
app.mainloop()
在 add_new_device()
中,您从全局 df
复制系列并附加新记录,然后使用新系列创建一个新数据帧 df2
并保存到文件。但是您忘记更新全局 df
以使其不包含新设备。下次要添加另一个新设备时,您再次从全局 df
复制系列,其中没有以前添加的设备,附加当前的新设备并保存到文件。然后将在没有先前添加的设备的情况下覆盖该文件。
要解决此问题,您需要更新全局 df
而不是创建新数据框 df2
。还建议将全局 df
作为 class 变量移动到 MedicalDevices
中:
class MedicalDevices:
# excel file path
f_path = "medical_devices_data.xlsx"
df = pd.read_excel(f_path, sheet_name="Sheet1")
...
def add_new_device(newDevice):
# update class dataframe `df` instead of creating new one
MedicalDevices.df = MedicalDevices.df.append({
"Name": newDevice.name,
"Serial": newDevice.sn,
"Manufacture": newDevice.manufacture,
"Model": newDevice.model,
"Supplier": newDevice.supplier,
"Department": newDevice.department,
"Warranty": newDevice.warranty_expire
}, ignore_index=True)
# export to file
MedicalDevices.df.to_excel(MedicalDevices.f_path, index=False)
print(f"A new device added with Serial#: {newDevice.sn}")