Tkinter Tutorial - Gestión de la disposición
En las secciones anteriores, hemos introducido varios tipos de widgets de Tkinter, como label, button, menú desplegable, etc. Mientras tanto, también hemos mencionado brevemente cómo diseñar estos widgets en la ventana del programa. Este es el punto clave que aprenderá en esta sección - los métodos de gestión de la geometría de Tkinter.
Tkinter tiene tres métodos de gestión de la geometría, es decir, pack
, grid
, y place
. Vamos a repasarlos uno por uno.
Método de disposición de Tkinter pack
El método pack
, como se indica literalmente, empaqueta el widget en el marco de la ventana después de ser creado. Nos encontramos con este método de empaquetado en la sección Tkinter Label donde también se listan todas las opciones de pack
.
Le mostraremos cómo diseñar widgets con el método pack
(también sus opciones). Unos pocos ejemplos ayudan a demostrar la configuración correcta.
Disposición de Tkinter pack
- Posición relativa
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West", width=15)
buttonW.pack(side="left")
buttonE = tk.Button(app, text="East", width=15)
buttonE.pack(side="right")
app.mainloop()
Ejecute el programa, obtendrá una ventana como esta,
Como puedes ver, buttonWest
se ajusta al lado izquierdo de la ventana y buttonEast
se ajusta al lado derecho de la ventana. Puede intentar escalar el tamaño de la ventana más abajo, pero verá que aún se aferran a los lados de la ventana y la posición relativa no cambiará.
buttonW.pack(side="left")
El lado
tiene cuatro opciones -
top
bottom
left
right
Coloca el widget en el side
de la ventana. Como se ilustra en el ejemplo, buttonW
se asigna en el lado izquierdo de la ventana, porque side='left'
, mientras que buttonE
está en el lado derecho de la ventana, porque side='right'
.
Ahora tenemos un escenario interesante, ¿qué pasa si dos widgets tienen la misma propiedad side
, cómo será el diseño?
Intenta responder tú mismo, o compruébalo ejecutando los siguientes códigos.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West", width=15)
buttonW.pack(side="left")
buttonE1 = tk.Button(app, text="East 1", width=15)
buttonE1.pack(side="right")
buttonE2 = tk.Button(app, text="East 2", width=15)
buttonE2.pack(side="right")
app.mainloop()
Tkinter pack
para añadir el relleno interno y externo del widget
En algunos casos, necesitas añadir algún relleno dentro o fuera del widget para que haya menos congestión entre los widgets, y también entre el texto del widget y los límites del mismo. Ahora, necesitas opciones como padx
, pady
, ipadx
y ipadx
.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonW = tk.Button(app, text="West")
buttonW.pack(side="left", ipadx=20, padx=30)
buttonE = tk.Button(app, text="East")
buttonE.pack(side="right", ipadx=20, padx=30)
app.mainloop()
Ambos botones añaden el relleno interior de 20 unidades y el exterior de 30 unidades en la x
, y la unidad es el píxel pero no el ancho de un carácter.
Tkinter pack
Layout Relleno en dirección x, y
La siguiente implementación de código podría llenar automáticamente la dimensión del widget al mismo ancho o alto que la ventana, y cuando se hace un zoom en la ventana, el tamaño del control puede cambiar automáticamente con el tamaño de la ventana.
import tkinter as tk
app = tk.Tk()
app.geometry("300x200")
buttonX = tk.Button(app, text="Fill X", bg="red", height=5)
buttonX.pack(fill="x")
buttonY = tk.Button(app, text="Fill Y", bg="green", width=10)
buttonY.pack(side="left", fill="y")
app.mainloop()
butonX.pack(fill='x')
significa que buttonX
llenará el ancho de toda la ventana. De forma similar, fill='y'
llenará la altura de toda la ventana, y mientras tanto fill='both'
llenará tanto el ancho como la altura.
Tkinter pack
Opción de diseño expand
- expandir automáticamente
La opción fill=
de arriba rellenará automáticamente el widget en dirección x
y/o y
cuando se modifique el tamaño de la ventana. Otro requisito similar es cómo mostrar automáticamente todo el contenido si el widget incluye múltiples opciones, como una lista?
import tkinter as tk
import calendar
app = tk.Tk()
buttonX = tk.Button(app, text="Label ", bg="blue", height=5)
buttonX.pack(fill="x")
listboxA = tk.Listbox(app, width=10)
listboxA.pack(fill="both", expand=1)
for i in range(1, 13):
listboxA.insert(tk.END, calendar.month_name[i])
app.mainloop()
Cuando expand=True
o expand=1
, la lista desplegará todos los elementos, desde January
a December
como se muestra en el ejemplo anterior.
Si expand
está configurado como False
, entonces la lista sólo muestra los primeros 10 elementos por defecto. Necesita usar el ratón o las teclas de dirección para mostrar los elementos ocultos después de que la lista de elementos sea seleccionada.
listboxA.pack(fill="both", expand=0)
expand=0
deshabilita la lista para mostrar automáticamente todos los elementos.
Método de diseño grid
de Tkinter
Tkinter grid
es otro y también el más importante método de geometría de diseño. Este es el que debería aprender si sólo quiere aprender un único método entre todos los gestores de geometría.
La grid
se usa a menudo en los cuadros de diálogo, y podría colocar los widgets basados en las coordenadas de posición de la cuadrícula. El método de diseño grid
podría tener posiciones relativas estables de todos los widgets.
El siguiente ejemplo creará una interfaz gráfica relativamente complicada comparada con los ejemplos anteriores, que usa tantas opciones de grid
como sea posible y que se explicarán en las siguientes secciones.
import tkinter as tk
app = tk.Tk()
labelWidth = tk.Label(app, text="Width Ratio")
labelWidth.grid(column=0, row=0, ipadx=5, pady=5, sticky=tk.W + tk.N)
labelHeight = tk.Label(app, text="Height Ratio")
labelHeight.grid(column=0, row=1, ipadx=5, pady=5, sticky=tk.W + tk.S)
entryWidth = tk.Entry(app, width=20)
entryHeight = tk.Entry(app, width=20)
entryWidth.grid(column=1, row=0, padx=10, pady=5, sticky=tk.N)
entryHeight.grid(column=1, row=1, padx=10, pady=5, sticky=tk.S)
resultButton = tk.Button(app, text="Get Result")
resultButton.grid(column=0, row=2, pady=10, sticky=tk.W)
logo = tk.PhotoImage(file="python.gif")
labelLogo = tk.Label(app, image=logo)
labelLogo.grid(
row=0,
column=2,
columnspan=2,
rowspan=2,
sticky=tk.W + tk.E + tk.N + tk.S,
padx=5,
pady=5,
)
app.mainloop()
Opciones de grid
, column
y row
de Tkinter
labelWidth.grid(column=0, row=0, ipadx=5, pady=5, sticky=tk.W + tk.N)
Cada widget será colocado en la celda absoluta en el método de diseño grid
. La coordenada de la celda se determina por column
y row
.
El widget labelWidth
se coloca en la celda de la posición (0, 0)
. La coordenada comienza en la esquina superior izquierda de la ventana.
Las opciones ipadx
, ipady
, padx
y pady
son las mismas que las del método pack
.
Opción grid
sticky
de Tkinter
sticky
determina cómo se pega el widget a la celda cuando el widget es más pequeño que la celda.
sticky |
Significado |
---|---|
W |
pegarse a la izquierda |
E |
mantenerse a la derecha |
N |
pegarse a la parte superior |
S |
adherirse al fondo |
La opción sticky
por defecto es el centro, es decir, W+E+N+S
.
Opciones columnspan
y rowspan
de Tkinter
labelLogo.grid(
row=0,
column=2,
columnspan=2,
rowspan=2,
sticky=tk.W + tk.E + tk.N + tk.S,
padx=5,
pady=5,
)
La coordenada de la celda de labelLogo
es (column=2, row=0)
y el tamaño del logo es relativamente grande, por lo que se asigna un tamaño de celda de 2x2
. arrowspan = 2
y rowspan=2
significan que el widget tiene tramos de dos celdas en las direcciones X
y Y
empezando desde la posición del widget.
Método place
de Tkinter
El método place
de Tkinter coloca el widget en una posición absoluta o relativa en la ventana. Seguimos usando el mismo enfoque de arriba para introducir las opciones de este método de diseño.
import tkinter as tk
app = tk.Tk()
app.geometry("300x300")
labelA = tk.Label(app, text="Label (0, 0)", fg="blue", bg="#FF0")
labelB = tk.Label(app, text="Label (20, 20)", fg="green", bg="#300")
labelC = tk.Label(app, text="Label (40, 50)", fg="black", bg="#f03")
labelD = tk.Label(app, text="Label (0.5, 0.5)", fg="orange", bg="#0ff")
labelA.place(x=0, y=0)
labelB.place(x=20, y=20)
labelC.place(x=40, y=50)
labelD.place(relx=0.5, rely=0.5)
app.mainloop()
Tkinter place
Posición absoluta
labelA.place(x=0, y=0)
labelB.place(x=20, y=20)
Las opciones x=
y y=
en place
determinan las posiciones absolutas del widget, que tienen la unidad como pixel. Por ejemplo, lableB.place(x=20, y=20)
significa que labelB
se coloca en la coordenada de (20, 20)
.
Posición relativa de Tkinter place
El inconveniente de la posición absoluta es que si hay otros widgets en la ventana colocados con posiciones relativas, cuando la ventana se amplía, el widget que usa la disposición de posición absoluta posiblemente tendrá la superposición con otros widgets.
El método de diseño place
también tiene la opción de posición relativa, es decir,
labelD.place(relx=0.5, rely=0.5)
Donde relx
y rely
están en el rango de 0.0~1.0
. Es el porcentaje relativo de la posición del widget con respecto al tamaño de la ventana.
Por ejemplo, relx=0.5, reli=0.5
significa que el widget se coloca en el 50% de la anchura y el 50% de la altura de la ventana.
relx=1.0
es el límite derecho de la ventana, y rely=1.0
es el límite inferior de la ventana.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook