Pequeños detalles que hacen grande tu GUI en Tkinter
A menudo, una aplicación de escritorio se percibe como “de prueba” porque la interfaz carece de pulido. Con unos ajustes simples puedes transformar cualquier ventana de Tkinter en una experiencia profesional, accesible y agradable. En este artículo repasamos los aspectos clave de usabilidad y accesibilidad que todo desarrollador debe aplicar.
1. Tamaños mínimos y comportamiento al redimensionar
Antes (sin control)
- Ventana sin
minsize→ el usuario puede colapsar la UI hasta que los widgets desaparecen. - Widgets con
packsinfillpueden quedar desalineados al cambiar el tamaño.
Después (buena práctica)
- Define
root.minsize(width, height)basado en el contenido más grande. - Usa
gridconsticky="nsew"yrowconfigure/columnconfigurepara que los widgets escalen de forma controlada. - Implementa
root.resizable(True, False)si solo deseas redimensionar horizontalmente.
root = tk.Tk()
root.title("Ejemplo profesional")
root.minsize(400, 250) # Evita que la ventana sea demasiado pequeña
root.resizable(True, True)
# Configuración de la cuadrícula
for i in range(3):
root.columnconfigure(i, weight=1, minsize=100)
root.rowconfigure(i, weight=1, minsize=50)
2. Uso correcto de los estados disabled y normal
Mostrar claramente cuándo una acción está disponible o no evita frustración. Además, los estados deshabilitados son leídos por lectores de pantalla, mejorando la accesibilidad.
Mala práctica
- Desactivar botones sin indicar la razón.
- Ocultar campos en lugar de deshabilitarlos.
Mejor práctica
- Utiliza
state="disabled"y muestra un tooltip explicativo. - Cuando el usuario completa un campo, habilita los controles dependientes.
# Botón que depende de la validación del Entry
btn_send = ttk.Button(root, text="Enviar", state="disabled")
# Tooltip sencillo con ttkbootstrap
btn_send.tooltip = "Introduce un número válido antes de enviar"
# Función que habilita el botón cuando la entrada es válida
def on_valid(event):
if entry_var.get().isdigit():
btn_send.config(state="normal")
else:
btn_send.config(state="disabled")
3. Mensajes de error claros y útiles
Un mensaje de error debe responder a tres preguntas: qué ocurrió, por qué y cómo solucionarlo. Evita textos genéricos como "Error".
Ejemplo pobre
messagebox.showerror("Error", "Valor inválido")
Ejemplo mejorado
msg = (
"El valor ingresado debe ser un número entero entre 1 y 9999.\n"
"Por favor, corrige el campo y vuelve a intentarlo."
)
messagebox.showerror("Entrada no válida", msg)
Consejos adicionales:
- Usa
messagebox.showwarningpara errores recuperables. - Resalta visualmente el widget problemático (p.ej., borde rojo).
4. Validar que el Entry acepte solo números
Hay tres enfoques habituales en Tkinter:
- Validación en tiempo real con
registeryvalidate='key'. - Validación al perder el foco usando
<FocusOut>. - Validación al enviar con una función centralizada.
Validación en tiempo real
def solo_numeros(text):
return text.isdigit() or text == ""
vcmd = (root.register(solo_numeros), "%P")
entry_num = ttk.Entry(root, validate="key", validatecommand=vcmd)
Validación al enviar (centralizada)
def enviar():
valor = entry_var.get()
if not valor.isdigit():
messagebox.showerror(
"Entrada no válida",
"Solo se permiten números enteros."
)
entry.focus_set()
return
# Procesar el número
print(f"Número aceptado: {valor}")
Combina ambas técnicas para máxima robustez: evita que el usuario escriba caracteres no permitidos y muestra un mensaje definitivo al intentar enviar.
5. Toques finales que marcan la diferencia
- Consistencia tipográfica: usa la familia
HelveticaoSegoe UIy tamaños entre 10‑12 pt. - Espaciado y márgenes: aplica
padx/padyuniformes (ej. 8 px) en todos los contenedores. - Iconografía: añade íconos de Material Icons mediante
tk.PhotoImagepara botones críticos. - Accesibilidad: define
widget.configure(takefocus=True)y usattk::stylepara contraste de colores ≥ 4.5:1. - Modo oscuro: con
ttkbootstrappuedes cambiar el tema con una sola línea:style = ttk.Style(); style.theme_use('darkly').
Aplicar este conjunto de buenas prácticas no solo eleva la apariencia, sino que también reduce los tickets de soporte y mejora la percepción del usuario final.