Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter][Python3.6] Referir a un widget desde dentro de una clase
#1
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.

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('')
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??
Responder
#2
Hola Alfredo, ¿cuál es la línea de código que arroja el error y cuál es el error exactamente?

Saludos
¡No te pierdas nuestro curso oficial en Udemy para aprender Python, bases de datos SQL, orientación a objetos, tkinter y mucho más!

También ofrecemos consultoría profesional de desarrollo en Python para personas y empresas.
Responder
#3
Hola Francisco, ese código en si no arroja ningún error. El problema es si intento hacer referencia a una etiqueta desde esa clase que me dice:

AttributeError: 'DataFrameTreeView' object has no attribute 'label'
Responder
#4
Eso es porque el objeto "label" lo habrás creado en otra clase. Podés pasarla como argumento a DataFrameTreeView para tener acceso a sus objetos.
¡No te pierdas nuestro curso oficial en Udemy para aprender Python, bases de datos SQL, orientación a objetos, tkinter y mucho más!

También ofrecemos consultoría profesional de desarrollo en Python para personas y empresas.
Responder


Salto de foro:


Usuarios navegando en este tema: 2 invitado(s)