I have an application where I have my main code in a file called main.py and the functions and classes in another file called events.py. Well I have a class like this and what happens to me is that anywhere in the code I can put self.label and I refer to a label of my application, which is created in main.py, but within this class if I put self.label throws me an error because it seems that self in this case is the class itself or something like that. How can I refer to a widget from within this class? This class what it does is show a dataframe in a TreeView widget and I want in the process of creating the table to change an image that I have in a label.
class DataFrameTreeView(tk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.config(bg="#FFF4DC")
self.tree_view = None
self.hscrollbar = None
self.vscrollbar = None
self._data = None
def load_table(self, df, columns=None, columns_headers=None, chunk_size=20):
"""
Args:
path: cadena -> ruta al fichero .xlsx
columns: list -> columnas a mostrar en la tabla, si es None se,muestran todas
columns_headers: list -> Nombres para las cabeceras de las columnas,
si es None se usan las cabeceras del DataFrame
chunk_size: int -> Número de filas creadas por iteración
"""
if columns is not None:
dif = set(columns) - set(df.columns)
if dif:
raise ValueError(f"Columns: {tuple(dif)} are not in DataFrame")
else:
columns = df.columns
if columns_headers is not None:
if len(columns_headers) != len(df.columns):
raise ValueError("headers length not mismath columns number")
else:
columns_headers = columns
tk_col_names =[f"#{name}" for name in columns_headers]
# Treeview y barras
if self.tree_view is not None:
self.tree_view.destroy()
self.hscrollbar.destroy()
self.vscrollbar.destroy()
self.tree_view = ttk.Treeview(self, columns=tk_col_names)
self.vscrollbar = ttk.Scrollbar(self, orient='vertical', command = self.tree_view.yview)
self.vscrollbar.pack(side='right', fill=tk.Y)
self.hscrollbar = ttk.Scrollbar(self, orient='horizontal', command = self.tree_view.xview)
self.hscrollbar.pack(side='bottom', fill=tk.X)
self.tree_view.configure(yscrollcommand=self.vscrollbar.set)
self.tree_view.configure(xscrollcommand=self.hscrollbar.set)
w=self.winfo_reqwidth()
# Configuar columnas y cabeceras
for name, header, col in zip(tk_col_names, columns_headers, columns):
self.tree_view.column(name, anchor='c', width=round(w*0.3), stretch=True, minwidth=120)
self.tree_view['show'] = 'headings'
# Cargamos los items
rows = df.shape[0]
chunks = rows / chunk_size
progress = 0
step = 100 / chunks
arial14 = font.Font(family='Arial', size=14)
progress_bar = ttk.Progressbar(self, orient="horizontal",
length=100, mode="determinate")
label_value = tk.StringVar(value="Loading...")
progress_bar["value"] = progress
label = tk.Label(self, textvariable=label_value, font=arial14, bg="#FFF4DC")
label.place(relx=0.50, rely=0.4, anchor=tk.CENTER)
progress_bar.place(relx=0.5, rely=0.5, relwidth=0.80, anchor=tk.CENTER)
for ind in df.index:
if ind > 0.25*rows:
label_value.set("Reading File...")
if ind > 0.50*rows:
label_value.set("Preprocessing...")
if ind > 0.80*rows:
label_value.set("Analyzing...")
values = [str(v) for v in df.loc[ind, columns].values]
self.tree_view.insert("", tk.END, text=ind+1, values=values)
if ind % chunk_size == 0:
self.update_idletasks()
progress += step
progress_bar["value"] = progress
progress_bar["value"] = progress
self.update_idletasks()
progress_bar.destroy()
label.destroy()
self.tree_view.pack(expand=True, fill='both')
self._data = df[columns].copy()
# Creamos columna en dataframe local con los items
self._data.columns = tk_col_names
self._data["#iids"] = self.tree_view.get_children('')