Hola muy buenas, tengo una aplicación en la que tengo mi código principal en un archivo llamado main.py y las funciones y las clases en otro archivo llamado events.py. Bien pues tengo un clase como esta y lo que me ocurre es que en cualquier parte del codigo yo puedo poner self.label y hago referencia a una etiqueta de mi aplicacion, que esta creada en main.py, pero dentro de esta clase si pongo self.label me tira un error porque parece que self en este caso es la propia clase o algo asi. Como puedo hacer para referirme a u widget desde dentro de esta clase? Esta clase lo que hace es mostrar un dataframe en un widget TreeView y quiero que en el proceso de creación de la tabla cambie una imagen que tengo en un label.
La idea es que mientras carga el treeview ir cambiando una imagen que tengo un Label simulando una "animación". Algun consejo de como hacerlo??
Código:
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('')