python - examples - tkinter grid
¿Cómo empacar un widget tkinter debajo de un widget existente que se ha empaquetado en el lado izquierdo? (3)
Estoy intentando escribir una GUI básica de Tkinter que tenga un widget de Text
en la parte superior, luego un widget de Button
alineado a la izquierda debajo de él, y luego otro widget de Text
debajo del botón. El problema que tengo es que, después de empaquetar el widget Button
a la izquierda, cuando voy a empacar el segundo widget de Text
, lo coloco al lado del botón a la derecha, en lugar de debajo del botón. Esto sucede independientemente de lo que establezca el argumento side
para el segundo widget de Text
Aquí hay una pieza simple de código que demuestra este comportamiento:
from Tkinter import *
root = Tk()
w = Text(root)
w.pack()
x = Button(root, text="Hi there!")
x.pack(side=LEFT)
y = Text(root)
y.pack(side=BOTTOM)
root.mainloop()
Entonces, ¿cómo voy a configurar el segundo widget de Text
para que aparezca debajo del botón, en lugar de a la derecha?
El embalaje ocurre en el orden en que se llaman los métodos .pack, por lo que una vez que x ha "reclamado" el lado izquierdo, eso es todo: ocupará la parte izquierda de su elemento primario y todo lo demás dentro de su elemento primario estará a su derecha. Necesita un Marco para "mediar", por ejemplo ...:
from Tkinter import *
root = Tk()
w = Button(root, text="Mysterious W")
w.pack()
f = Frame(root)
x = Button(f, text="Hi there!")
x.pack()
y = Button(f, text="I be Y")
y.pack(side=BOTTOM)
f.pack(side=LEFT)
root.mainloop()
(Cambié Textos a Botones para una visibilidad más inmediata del diseño solamente - el Tkinter en esta Mac no muestra los Textos claramente hasta que tienen foco, pero los Botones son bastante claros ;-).
En general, hay dos soluciones a los problemas de diseño:
cambiar a usar la rejilla. Se vuelve realmente fácil hacer diseños como lo que estás tratando de lograr. Grid puede resolver probablemente el 95% de todos los problemas de diseño (es increíble cuando lo piensas; ¡Tk hace con un gerente lo que la mayoría de los kits de herramientas necesitan media docena para lograr!)
usa múltiples marcos Si algunos widgets necesitan apilarse de arriba a abajo y algunos de izquierda a derecha, no siempre se puede obtener lo que se desea empaquetando todo en un solo cuadro. Utilice un marco para las partes de arriba a abajo del diseño y marcos adicionales para el contenido de izquierda a derecha.
También tenga en cuenta que los widgets no tienen que ser elementos secundarios del widget en el que están empaquetados / grillados. Puede usar el parámetro "in" para colocar widgets en algún otro contenedor que no sea el principal.
Por ejemplo, en su ejemplo específico, puede crear tres marcos, arriba, medio, abajo. Empaque estos de arriba a abajo en su ventana de nivel superior. Luego puede empaquetar el primer widget de texto en la parte superior, el botón o los botones horizontalmente en el medio, y el otro widget de texto en la parte inferior.
La ventaja de este enfoque es que hace que sea mucho más fácil cambiar el diseño en el futuro (que en mi experiencia siempre sucede en algún momento). No tiene que reaparecer ninguno de sus widgets, simplemente empaquételos / colóquelos en otro contenedor.
En su breve ejemplo, no hace mucha diferencia, pero para aplicaciones complejas, esta estrategia puede ser un salvavidas.
Mi mejor consejo es este: el diseño no es una idea de último momento. Haga un poco de planificación, tal vez incluso pase cinco minutos dibujando en papel cuadriculado. Primero decida sobre las principales regiones de su aplicación y use un marco o algún otro contenedor para cada una (ventana cuadrada, cuaderno, etc.). Una vez que tenga esos, haga el mismo enfoque de dividir y vencer para cada sección. Esto le permite usar diferentes tipos de diseño para diferentes secciones de su aplicación. Las barras de herramientas obtienen un diseño horizontal, los formularios pueden tener un diseño vertical, etc.
Inicialmente no entendía cómo funcionaba el empaque y no me di cuenta de que todo el lado izquierdo estaba siendo "reclamado" cuando hice x.pack(side=LEFT)
. Lo que encontré después de leer esto y la respuesta de Alex aquí es que no estaba realmente después de tener x
empaquetado en el lado izquierdo, sino más bien tenerlo anclado a la izquierda, usando anchor=W
(W para Oeste) en lugar de side=LEFT
. Mi fragmento de código revisado, que hace lo que yo buscaba, se ve así:
from Tkinter import *
root = Tk()
w = Text(root)
w.pack()
x = Button(root, text="Hi there!")
x.pack(anchor=W)
y = Text(root)
y.pack(side=BOTTOM)
root.mainloop()
De esta forma, x
ya no está "reclamando" el lado izquierdo, simplemente está alineado con la izquierda (u oeste) dentro de su bloque de espacio.