1

estoy convirtiendo los programas que ya he hecho en python a programas utilizando el paradigma de programacion POO, al hacer esto me surgen ciertas dudas, Adjunto mi codigo aqui:

import tkinter as tk 

class Calculadora(tk.Frame):
    def __init__(self,root = None):
        super().__init__(root)
        self.root = root
        self.root.title("Calculadora")
if __name__ == "__main__":
    App = Calculadora(root = tk.Tk())
    App.mainloop()

¿Porque al instanciar la clase Calculadora y pasarle como argumento root = tk.Tk crea la ventana?

¿Porque la clase Calculadora debe heredar de tk.Frame?

¿Porque al usar el metodo super() tengo que llamar a root si este es parte del constructor de la clase Calculadora? , no se supone que super() es para heredar los atributos y demas de la clase padre?

Franco
  • 682
  • 4
  • 16

1 Answers1

3

¿Por qué al instanciar la clase Calculadora y pasarle como argumento root = tk.Tk crea la ventana?

La ventana se crea porque instancias tk.Tk, clase base para cualquier aplicación de Tkinter y que inicia el intérprete TCL y el ciclo de eventos. Es decir, lo que inicia la ventana es tk.Tk(). Luego, para que el Frame de tu clase Calculadora pueda dibujarse en la ventana principal debes pasarle una instancia de esta ventana principal o una instancia de otro widget que ya pertenezca a esta ventana si fuera un widget anidado. Es exactamente lo mismo que cuando haces tk.Button(parent, text=...) por ejemplo.

App.mainloop() es el método de tk.Tk encargado de iniciar el ciclo de eventos y por tanto de mostrar la ventana. Dicho método lo hereda Calculadora de tk.Frame que en esencia llama al método mainloop de la ventana principal.

Realmente no es imprescindible pasar una instancia de tk.Tk, si no lo haces implícitamente se genera una instancia de la misma a la que puedes acceder desde la instancia del Frame mediante el atributo master:

import tkinter as tk 

class Calculadora(tk.Frame):
    def __init__(self,root = None):
        super().__init__(root)
        self.master.title("Calculadora")

if __name__ == "__main__":
    app = Calculadora()
    app.mainloop()

¿Por qué la clase Calculadora debe heredar de tk.Frame?

No tendría por qué heredar de tk.Frame, podría heredar de tk.Toplevel, tk.Button, tk.Canvas, etc. O no heredar de nada y en vez de herencia usar composición, todo depende de cómo queramos estructurar la app.

import tkinter as tk

class Calculadora:
    def __init__(self, root):
        self.root = root
        self.root.geometry("100x100")
        self.master_frame = tk.Frame(root)
        self.master_frame.pack(fill=tk.BOTH, expand=True)
        self.root.title("Calculadora")
        btn = tk.Button(self.master_frame, text="Hola")
        btn.pack()

if __name__ == "__main__":
    root = tk.Tk()
    app = Calculadora(root)
    root.mainloop()

tk.Frame es un widget básico, representa simplemente una región rectangular en la pantalla con solo un puñado de características o atributos básicos (color de fondo, margenes, padding, bordes, etc). Esto lo hace muy útil como widget base para cualquier otro widget que queramos implementar o como contenedor de otros widgets. Esta es la raźón por la que se suele heredar de tk.Frame, tu clase Calculadora al heredar de tk.Frame se convierte en un widget de Tkinter herendando con ello sus atributos y métodos, entre ellos pack, grid y place por ejemplo.

¿Por qué al usar el método super() tengo que llamar a root si este es parte del constructor de la clase Calculadora? , no se supone que super() es para heredar los atributos y demás de la clase padre?

En super().__init__(root) no llamas a root, lo que haces es pasar al método __init__ de la clase padre (tk.Frame) la instancia de la ventana principal para que tu clase pueda ser inicializada de forma correcta (y que entre otras cosas no cree una instancia tk.Tk implícita como hemos visto).

Al tener Calculadora un método __init__ definido se sobrescribe el heredado de tk.Frame. Si no llamas al método __init__ del padre todas las tareas esenciales de inicialización que se llevan a cabo en él no tendrán lugar y simplemente tu clase Calculadora será inútil porque no va a ser algo que se comporte como un widget de tkinter.

Para más información de que es y que hace super ver:

FJSevilla
  • 55,603
  • 7
  • 35
  • 58