¿Por qué usar clases al programar una tkinter gui en python?


19

Programo principalmente en Python y he programado un par de GUI con Tkinter, cada tutorial que he visto ha recomendado definir y usar una clase para la GUI, pero mi GUI se ejecuta sin problemas utilizando solo procedimientos, sin una clase.

¿Por qué usar una clase? Desde mi perspectiva, parece ser simplemente una capa adicional de complejidad y código innecesario.

Respuestas:


19

¿Por qué usar una clase? Porque facilita el trabajo, suponiendo que sepa cómo hacer una programación orientada a objetos y suponiendo que está escribiendo una GUI no trivial. El uso de objetos le permite dividir fácilmente su código en unidades modulares que son autónomas, y modularizar su código generalmente se considera una práctica recomendada.

La programación de la GUI se presta fácilmente a un estilo orientado a objetos, ya que una GUI está compuesta completamente de objetos: etiquetas, botones, barras de desplazamiento, áreas de texto, etc. Como ya está usando objetos, organizar su código en objetos más grandes tiene sentido . La barra de herramientas es un objeto, la barra de estado es un objeto, el panel de navegación es un objeto, el área principal es un objeto, cada pestaña del cuaderno es un objeto, etc.

Incluso cuando su código no es muy complejo, desde un punto de vista más práctico, le permite definir enlaces y devoluciones de llamada antes en el archivo que la definición de la función que está llamando, lo que creo que tiene mucho sentido.

Por ejemplo, considere un ejemplo simple (suponiendo que tkinter se haya importado como import tkinter as tk(python3) o import Tkinter as tk(python2):

def quit(event=None):
    sys.exit()
root = tk.Tk()
label = tk.Label(root, text="Hello, world")
label.pack()
label.bind("<1>", quit)
root.mainloop()

Para mí, el flujo de ese código está todo mal. Tengo que definir el método de salida antes de hacer referencia a él, y la creación de la ventana raíz y la llamada al mainloop están separadas por el resto del código.

Al usar clases, sin embargo, puedo escribir el código en un orden más natural:

class MyWindow(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Hello, world")
        label.pack()
        label.bind("<1>", self.quit)
    def quit(self, event=None):
        sys.exit()

root = tk.Tk()
MyWindow(root).pack()
root.mainloop()

El cuerpo principal de la GUI está justo en la parte superior del archivo, y el código de soporte está debajo de él. Ahora, por supuesto, puede usar funciones para lograr casi lo mismo. Sin embargo, en mi opinión, las clases hacen que todo sea un poco más fácil.

Otra ventaja es que ahora puedo cambiar fácilmente la ventana que contiene sin tener que cambiar nada de la ventana "principal" (y viceversa). Es decir, puedo agregar bordes o una nueva sección completa a la GUI principal, pero no tengo que tocar una sola línea de código dentro de MyWindow. Compare eso con el código de procedimiento donde podría tener que cambiar la label.pack()declaración y las declaraciones del paquete (o cuadrícula) de todos los otros widgets en la interfaz de usuario.

Sin embargo, dicho todo esto, no es necesario utilizar un enfoque orientado a objetos para escribir un código bueno, limpio y fácil de mantener. Se puede ser, pero también puede conducir a la mala código. Al final del día, un enfoque orientado a objetos es solo una herramienta. Si lo usa o no, y si lo usa correctamente o no depende de muchos factores. Por lo tanto, puede ser que para usted, y para el código que escriba, un estilo funcional sea perfectamente aceptable. Creo que descubrirá que a medida que sus programas se vuelven más complejos, un enfoque orientado a objetos facilitará la organización y el mantenimiento de su código.


¿Por qué usaste un marco en el segundo ejemplo? ¿No podrías evitarlo como lo hiciste en el primer ejemplo? ¿Hay algún secreto detrás de usar Frame con clases?
multigoodverse

2
El marco es simplemente por conveniencia. No hay ningún secreto para heredar de Frame. Podría haber heredado de objecto de cualquier otra clase, pero generalmente termino creando un marco de todos modos. Si estoy poniendo todo en un marco, tiene sentido hacer que la clase sea un marco. .
Bryan Oakley

1
Tiene sentido, gracias! Además, he visto a otros usar self antes de las variables, pero veo que estás usando algo como en label=tk.Label()lugar de self.tk.Label(). ¿Es esa una elección de estilo? Aquí hay un ejemplo usando self: python-textbok.readthedocs.org/en/1.0/…
multigoodverse

1
@BryanOakley, supongo que querías usar padre en lugar de raíz en la siguiente línea de MyWindow .__ init__: "label = tk.Label (root, text =" Hello, world ")"
user3885927

1
@ usuario3885927: ¡sí! Wow, le tomó casi tres años a alguien darse cuenta de eso. Sin embargo, no, parentsino más bien self, ya que la clase en sí misma es un Marco. ¡Gracias!
Bryan Oakley
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.