Lo que le debes pasar siempre a todo widget (incluidas StringVar
y demás variables) es una referencia al widget padre, punto. Si no se pasa ninguna referencia el padre será la ventana principal y esto puede dar problemas inesperados:
El widget padre es el widget que contiene a nuestro widget a instanciar.
Bien, ahora vamos a ver tu ejemplo. Tiene una clase Application
que deriva de Frame
y dentro instancias un TreeView
. self
hace referencia a la instancia de esa clase, es decir es un ttk.Frame
. La pregunta que debes hacerte es:
¿Dónde quiero ubicar mi TreeView
?
Si usas main_window
lo ubicas en la ventana principal, es decir, es un widget hermano del frame Application
.
Si usas self
lo ubicas dentro del Frame
que a su vez está dentro de main_window
.
La lógica nos dice que Application
es el widget contenedor base de toda la app y que el Treeview
y todo widget de la app debería estar dentro del mismo. Lo lógico es usar self
como padre. De hecho es común usar Frames como base geométrica para estructurar los distintos nieveles de la app.
Ten en cuenta que los administrados de geometría, métodos grid
, pack
y place
, actúan ubicando en el widget padre, no es lo mismo por tanto ubicar fuera o dentro del Frame
.
Mejor un ejemplo:
import tkinter as tk
from tkinter import ttk
class Application(ttk.Frame):
def __init__(self, main_window):
super().__init__(main_window)
main_window.title("Explorador de archivos y carpetas")
s = ttk.Style()
s.configure('My.TFrame', background='red')
self["style"] = 'My.TFrame'
self.btn1 = tk.Button(main_window, text="Botón 1")
self.btn1.pack()
self.btn2 = tk.Button(self, text="Botón 2")
self.btn2.pack()
if __name__ == "__main__":
root = tk.Tk()
root.geometry("600x400")
root.configure(background='green')
Application(root).pack(side="top", fill="both", expand=True)
root.mainloop()
He usado pack
y dos botones por comodidad, pero esto es irrelevante. Le he asignado un fondo verde a la ventana principal y uno rojo al Frame
(Application).
Si usamos main_window
como padre del primer botón y self
para el segundo:
self.btn1 = tk.Button(main_window, text="Botón 1")
self.btn2 = tk.Button(self, text="Botón 2")
Si usamos self
para ambos:
self.btn1 = tk.Button(self, text="Botón 1")
self.btn2 = tk.Button(self, text="Botón 2")
Si usamos main_window
para ambos:
self.btn1 = tk.Button(main_window, text="Botón 1")
self.btn2 = tk.Button(main_window, text="Botón 2")
¿Para que queremos el Frame
? Para eso no derivamos de ttk.Frame
y creamos todo en la ventana principal...
¿super().__init__(main_window) conceptualmente equivalente a self = ttk.Frame(main_window)? – Chemag Apr 15 '20 at 08:19