Estoy aprendiendo a escribir progtwigs impulsados por eventos usando tkinter y estoy usando el excelente tutorial de Fredrik Lundh. En eso, él menciona que es mejor definir una clase (Aplicación) para el marco y ejecutar el progtwig como una instancia de la clase en lugar de simplemente iniciarlo así:
root = Tk() w = Label(root, text = 'hello, world!') w.pack() root.mainloop()
Tengo 3 preguntas:
¿Es una mala práctica de progtwigción hacerlo de esta manera más simple?
Si defino una clase, con funciones de callback vinculadas a los widgets, ¿todas las funciones tienen que estar dentro de la propia clase? es decir, ¿puedo tener un botón que diga ir dentro de la clase, que cuando hago clic ejecuta una rutina elaborada que se ha definido fuera de la clase?
¿Es una mala práctica tomar el resultado generado fuera de la clase y mostrarlo dentro?
Esencialmente, puedo hacer que el progtwig funcione saltando dentro y fuera de la clase, pero no estoy seguro de que sea una mala práctica hacerlo (a las variables globales).
Ejemplo:
import tkinter import random class Application(tkinter.Frame): @classmethod def main(cls): root = tkinter.Tk() frame = cls(root) frame.grid() root.mainloop() def __init__(self, master=None, cnf={}, **kw): super().__init__(master, cnf, **kw) self.w = tkinter.Label(self, text='Hello, world!') self.w.grid() self.v = tkinter.Button(self, text='Press Me', command=self.click) self.v.grid() self.u = tkinter.Button(self, text='Me Too!', command=lambda: external_mutator(self.w)) self.u.grid() def click(self): self.w['text'] = external_function(3) def external_function(ndigits): return round(random.random(), ndigits) def external_mutator(widget): widget['text'] = external_function(6) print('Hello to you too!') # shown on console if present if __name__ == '__main__': Application.main()
Alternativa al método de clase main
:
import tkinter import random class Main(tkinter.Tk): def __init__(self, screenName=None, baseName=None, className='Tk', useTk=1, sync=0, use=None): super().__init__(screenName, baseName, className, useTk, sync, use) frame = Application(self) frame.grid() self.mainloop() class Application(tkinter.Frame): def __init__(self, master=None, cnf={}, **kw): super().__init__(master, cnf, **kw) self.w = tkinter.Label(self, text='Hello, world!') self.w.grid() self.v = tkinter.Button(self, text='Press Me', command=self.click) self.v.grid() self.u = tkinter.Button(self, text='Me Too!', command=lambda: external_mutator(self.w)) self.u.grid() def click(self): self.w['text'] = external_function(3) def external_function(ndigits): return round(random.random(), ndigits) def external_mutator(widget): widget['text'] = external_function(6) print('Hello to you too!') # shown on console if present if __name__ == '__main__': Main()
1) Yo diría que para este ejemplo, no está necesariamente mal. El progtwig se ejecuta. La verdadera preocupación es que a medida que comienza a crear progtwigs más complejos, es posible que desee un formato más estructurado. Las clases pueden ayudar.
2) No todas las funciones tienen que estar dentro de la propia clase. Los métodos pueden llamar a funciones externas. La razón principal para tener un método en lugar de una función es que el método tiene acceso fácil a todos los atributos del objeto. Desea evitar que una función llegue a un objeto para manipular los atributos.
3) Es mejor pasar variables a una clase que definir variables globales, principalmente porque puede ser difícil mantener el scope.