La siguiente es la estructura general de mi programa típico de python tkinter.
def funA():
def funA1():
def funA12():
# stuff
def funA2():
# stuff
def funB():
def funB1():
# stuff
def funB2():
# stuff
def funC():
def funC1():
# stuff
def funC2():
# stuff
root = tk.Tk()
button1 = tk.Button(root, command=funA)
button1.pack()
button2 = tk.Button(root, command=funB)
button2.pack()
button3 = tk.Button(root, command=funC)
button3.pack()
funA
funB
y funC
abrirá otras Toplevel
ventanas con widgets cuando el usuario haga clic en los botones 1, 2, 3.
Me pregunto si esta es la forma correcta de escribir un programa de Python tkinter. Claro, funcionará incluso si escribo de esta manera, pero ¿es la mejor manera? Suena estúpido, pero cuando veo los códigos escritos por otras personas, su código no está desordenado con un montón de funciones y sobre todo tienen clases.
¿Existe alguna estructura específica que debamos seguir como buena práctica? ¿Cómo debo planificar antes de comenzar a escribir un programa de Python?
Sé que no existen las mejores prácticas en programación y tampoco las pido. Solo quiero algunos consejos y explicaciones para mantenerme en la dirección correcta, ya que estoy aprendiendo Python por mí mismo.
Respuestas:
Abogo por un enfoque orientado a objetos. Esta es la plantilla con la que empiezo:
Las cosas importantes a tener en cuenta son:
No uso una importación de comodines. Importo el paquete como "tk", lo que requiere que prefijo todos los comandos con
tk.
. Esto evita la contaminación del espacio de nombres global, además hace que el código sea completamente obvio cuando está utilizando clases Tkinter, clases ttk o algunas propias.La aplicación principal es una clase . Esto le brinda un espacio de nombres privado para todas sus devoluciones de llamada y funciones privadas, y generalmente facilita la organización de su código. En un estilo de procedimiento, debe codificar de arriba hacia abajo, definiendo funciones antes de usarlas, etc. Con este método no lo hace, ya que en realidad no crea la ventana principal hasta el último paso. Prefiero heredar
tk.Frame
solo porque normalmente empiezo creando un marco, pero de ninguna manera es necesario.Si su aplicación tiene ventanas de nivel superior adicionales, le recomiendo hacer de cada una de ellas una clase separada, heredando de
tk.Toplevel
. Esto le brinda las mismas ventajas mencionadas anteriormente: las ventanas son atómicas, tienen su propio espacio de nombres y el código está bien organizado. Además, facilita poner cada uno en su propio módulo una vez que el código comienza a crecer.Finalmente, es posible que desee considerar el uso de clases para cada parte importante de su interfaz. Por ejemplo, si está creando una aplicación con una barra de herramientas, un panel de navegación, una barra de estado y un área principal, puede crear cada una de esas clases. Esto hace que su código principal sea bastante pequeño y fácil de entender:
Dado que todas esas instancias comparten un padre común, el padre efectivamente se convierte en la parte "controlador" de una arquitectura modelo-vista-controlador. Entonces, por ejemplo, la ventana principal podría colocar algo en la barra de estado llamando
self.parent.statusbar.set("Hello, world")
. Esto le permite definir una interfaz simple entre los componentes, lo que ayuda a mantener el acoplamiento al mínimo.fuente
parent
, a menos que la vaya a usar más tarde. No lo guardé porque ninguno de los códigos en mi ejemplo requería que se guardara.Poner cada una de sus ventanas de nivel superior en su propia clase separada le permite reutilizar el código y una mejor organización del código. Cualquier botón y método relevante que esté presente en la ventana debe definirse dentro de esta clase. Aquí hay un ejemplo (tomado de aquí ):
Ver también:
Espero que ayude.
fuente
Esta no es una mala estructura; Funcionará bien. Sin embargo, debe tener funciones en una función para hacer comandos cuando alguien hace clic en un botón o algo
Entonces, lo que podría hacer es escribir clases para estos y luego tener métodos en la clase que manejen los comandos para los clics de los botones y tal.
Aquí hay un ejemplo:
Por lo general, los programas tk con múltiples ventanas son múltiples clases grandes y en
__init__
todas las entradas, etiquetas, etc. se crean y luego cada método es manejar eventos de clic de botónRealmente no hay una forma correcta de hacerlo, lo que sea que funcione para usted y haga el trabajo siempre que sea legible y puede explicarlo fácilmente porque si no puede explicar fácilmente su programa, probablemente haya una mejor manera de hacerlo .
Echa un vistazo a Pensar en Tkinter .
fuente
OOP debería ser el enfoque y
frame
debería ser una variable de clase en lugar de una variable de instancia .Referencia: http://www.python-course.eu/tkinter_buttons.php
fuente
TKinter
en Python 2. Recomendaría usartkinter
Python 3. También colocaría las últimas tres líneas de código debajo de unamain()
función y llamaría al final del programa. Yo definitivamente evitar el usofrom module_name import *
, ya que contamina el espacio de nombres global y puede reducir la legibilidad.button1 = tk.Button(root, command=funA)
ybutton1 = ttk.Button(root, command=funA)
si eltkinter
módulo de extensión también se estaba importando? Con la*
sintaxis, ambas líneas de código parecerían serlobutton1 = Button(root, command=funA)
. No recomendaría usar esa sintaxis.Organizar su aplicación usando la clase le facilita a usted y a otras personas que trabajan con usted depurar problemas y mejorar la aplicación fácilmente.
Puede organizar fácilmente su aplicación de esta manera:
fuente
Probablemente, la mejor manera de aprender cómo estructurar su programa es leyendo el código de otras personas, especialmente si se trata de un gran programa al que han contribuido muchas personas. Después de mirar el código de muchos proyectos, debe tener una idea de cuál debería ser el estilo de consenso.
Python, como lenguaje, es especial porque hay algunas pautas sólidas sobre cómo debe formatear su código. El primero es el llamado "Zen de Python":
En un nivel más práctico, está PEP8 , la guía de estilo para Python.
Con eso en mente, diría que su estilo de código realmente no encaja, particularmente las funciones anidadas. Encuentre una manera de aplanarlos, ya sea utilizando clases o moviéndolos a módulos separados. Esto hará que la estructura de su programa sea mucho más fácil de entender.
fuente
Yo personalmente no uso el enfoque orientado a objeciones, principalmente porque a) solo se interpone en el camino; b) nunca lo reutilizará como módulo.
pero algo que no se discute aquí es que debe usar subprocesos o multiprocesamiento. Siempre. de lo contrario, su aplicación será horrible.
simplemente haga una prueba simple: inicie una ventana y luego busque alguna URL o cualquier otra cosa. los cambios son su interfaz de usuario no se actualizará mientras se realiza la solicitud de red. Es decir, su ventana de aplicación se romperá. depende del sistema operativo en el que se encuentre, pero la mayoría de las veces, no se volverá a dibujar, todo lo que arrastre sobre la ventana estará pegado en él, hasta que el proceso vuelva al circuito principal de TK.
fuente