I'm working on a tkinter/customtkinter app to load data to MySQL. Below are the relevant classes. When I run this code to load a single file, I have no issues. The problem comes when I click self.load_another_button
in the class loading_window
. It properly brings me back to file_select
, but when I click self.fd_button
and select a file, it doesn't return anything. Is there a nuance with filedialog in tkinter? I set self.filedialog
to None
on __init__
wondering if I needed to clear the variable for some reason, but that didn't work either. Happy to clarify anything if there are questions. This is my first tkinter/customtkinter app, so have no real clue what I'm doing.
class base_window(ctk.CTk):
def __init__(self,title = None, **kwargs):
super().__init__(**kwargs)
self.title(title)
self.geometry('500x400')
self.grid_columnconfigure(0,weight=1)
class table_selector(base_window):
def __init__(self):
super().__init__(title='Select Table')
self.queries = queries()
self.frame = ctk.CTkFrame(self,corner_radius=0,fg_color='transparent')
self.val = ctk.StringVar()
self.table_list = self.get_tables_from_schema()
self.ts_label = ctk.CTkLabel(self.frame,text='Select Table to Load')
selfbo = ttk.Combobox(self.frame,textvariable=self.val,values=self.table_list)
selfbo.set(self.table_list[0])
self.frame.columnconfigure((0,1),weight=1)
selfbo.grid(row=1,column=0,padx=5,pady=5)
self.ts_label.grid(row=0,column=0,padx=5,pady=5,sticky='ew',columnspan=2)
self.frame.grid(row=0,column=0,padx=5,pady=5)
self.select_btn = ctk.CTkButton(self.frame,text='Select',command=self.select_btn_clicked)
self.select_btn.grid(row=1,column=1,padx=5,pady=5)
def run(self):
self.mainloop()
def get_tables_from_schema(self):
sql = self.queries.get_tables_from_schema_sql()
df = run_query(sql,user=user,password=password,database=schema)
table_list = df.iloc[:,0].to_list()
return table_list
def select_btn_clicked(self):
global table_to_load
table_to_load = selfbo.get()
self.fs = file_select()
self.destroy()
self.fs.run()
class file_select(base_window):
def __init__(self):
super().__init__(title='Select File to Load')
self.filedialog = None
self.entry_text = None
self.file_to_load = None
self.queries = queries()
self.frame = ctk.CTkFrame(self,corner_radius=0,fg_color='transparent')
self.fs_label = ctk.CTkLabel(self.frame,text='Select File to Load (Only CSV is currently supported)')
self.entry_text = ctk.StringVar()
self.entry = ctk.CTkEntry(self.frame,textvariable=self.entry_text,width=50)
self.fd_button = ctk.CTkButton(self.frame,text='Click to Select File',command=self.fd_btn_clicked)
self.load_btn = ctk.CTkButton(self.frame,text='Click to Load File',command=self.load_btn_clicked)
self.frame.columnconfigure((0,1),weight=1)
self.fs_label.grid(row=0,column=0,padx=5,pady=5,sticky='new',columnspan=2)
self.entry.grid(row=1,column=0,padx=5,pady=5,sticky='ew',columnspan=2)
self.fd_button.grid(row=2,column=0,padx=5,pady=5,sticky='ew')
self.load_btn.grid(row=2,column=1,padx=5,pady=5,sticky='ew')
self.frame.grid(row=0,column=0,sticky='ew',padx=5,pady=5)
def run(self):
self.mainloop()
def fd_btn_clicked(self):
self.filedialog = filedialog.askopenfilename(parent=self,initialdir=os.path.join(os.path.expanduser('~'),'Desktop'))
self.entry_text.set(self.filedialog)
def load_btn_clicked(self):
self.file_to_load = self.entry_text.get()
if self.file_to_load[-3:].lower() != 'csv':
self.error_window = error_window(message='File selected is not a csv. Please select a new file that is a csv, or exit the program')
self.error_window.add_restart_button('file_select')
self.error_window.run()
else:
self.check_load_file()
def check_load_file(self):
self.loading_window = loading_window(file_to_load=self.file_to_load)
self.destroy()
self.loading_window.run()
class loading_window(base_window):
def __init__(self, title='Loading File',file_to_load='', **kwargs):
super().__init__(title=title, **kwargs)
self.file_to_load = file_to_load
self.frame = ctk.CTkFrame(self,corner_radius=0,fg_color='transparent')
self.label = ctk.CTkLabel(self.frame,text=f'Validating and Loading File {file_to_load}')
self.progress = ctk.CTkProgressBar(self.frame,mode='indeterminate',indeterminate_speed=1)
self.progress.set(0)
self.label.grid(row=0,column=0,padx=5,pady=5,sticky='new')
self.progress.grid(row=1,column=0,padx=5,pady=5,sticky='ew')
self.frame.grid(row=0,column=0,padx=5,pady=5,sticky='ew')
self.load_file()
def load_file(self):
self.progress.start()
df = pd.read_csv(self.file_to_load)
df.columns = [i.strip() for i in df.columns]
l_table_columns = run_query(queries().get_columns_from_table(),format='list',user=user,password=password,database=schema)
if l_table_columns is not None:
d = {}
for i in l_table_columns:
d[i[0]] = i[1]
cols_to_load = []
for col in df.columns:
if col in d.keys():
cols_to_load.append(col)
if d[col] not in ['datetime','date','timestamp']:
df.loc[:,col] = df.loc[:,col].fillna(fillna_map()[d[col]]).astype(dtype_map()[d[col]])
df_to_load = df.loc[:,cols_to_load]
success_fail = df_to_db(df_to_load,table=table_to_load,user=user,password=password,database=schema)
selfplete_load(text=success_fail)
def complete_load(self,text):
self.progress.set(1)
self.progress.stop()
selfplete_label = ctk.CTkLabel(self.frame,text=text)
self.end_button = ctk.CTkButton(self.frame,text='Click to Exit Program',command=sys.exit)
self.load_another_button = ctk.CTkButton(self.frame,text='Click to Load Another File',command=self.load_another_btn_clicked)
selfplete_label.grid(row=2,column=0,padx=5,pady=5,sticky='ew')
self.end_button.grid(row=3,column=0,padx=5,pady=5,sticky='ew')
self.load_another_button.grid(row=4,column=0,padx=5,pady=5,sticky='ew')
self.frame.grid(row=0,column=0,padx=5,pady=5,sticky='ew')
def run(self):
self.mainloop()
def load_another_btn_clicked(self):
self.ts = table_selector()
self.destroy()
self.ts.run()