Ir al contenido

IDEAS PRÁCTICAS · ASIMOV INGENIERÍA

Pequeños detalles que hacen grande tu GUI en Tkinter

Aprende a pulir la experiencia de usuario en Tkinter con buenas prácticas de tamaños, redimensionado, estados, validación y mensajes claros para crear interfaces profesionales.

Imagen ilustrativa · James Harrison / Unsplash.

Table of contents

No titles in the blog post

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.

Representación del logotipo de Python sobre un fondo morado
Imagen ilustrativa · Brecht Corbeel / Unsplash.

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 pack sin fill pueden 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 grid con sticky="nsew" y rowconfigure/columnconfigure para 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.showwarning para 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:

  1. Validación en tiempo real con register y validate='key'.
  2. Validación al perder el foco usando <FocusOut>.
  3. 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 Helvetica o Segoe UI y tamaños entre 10‑12 pt.
  • Espaciado y márgenes: aplica padx/pady uniformes (ej. 8 px) en todos los contenedores.
  • Iconografía: añade íconos de Material Icons mediante tk.PhotoImage para botones críticos.
  • Accesibilidad: define widget.configure(takefocus=True) y usa ttk::style para contraste de colores ≥ 4.5:1.
  • Modo oscuro: con ttkbootstrap puedes 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.

© 2025 Tu Blog de Python – Todos los derechos reservados.