Ir al contenido

IDEAS PRÁCTICAS · ASIMOV INGENIERÍA

Widgets esenciales en Tkinter: Label, Button y Entry – Guía completa y práctica

Aprende a usar los widgets básicos de Tkinter (Label, Button y Entry) con ejemplos detallados, personalización de estilo, buenas prácticas y trucos de depuración.

Imagen ilustrativa · Emile Perron / Unsplash.

Table of contents

No titles in the blog post

Widgets esenciales en Tkinter: Label, Button y Entry

En esta guía paso‑a‑paso descubrirás cómo crear, personalizar y gestionar los tres widgets más usados en aplicaciones de escritorio con Tkinter, el toolkit estándar de Python.

Pantalla con un editor de código
Imagen ilustrativa · Chris Ried / Unsplash.

1. ¿Por qué estos tres widgets?

Un Label muestra información estática, un Button permite al usuario disparar acciones y un Entry captura texto de entrada. Juntos forman la base de cualquier interfaz: presentación, interacción y recolección de datos.

Características clave
  • Label: texto, imágenes, alineación, wraplength, justify.
  • Button: comandos, state (normal/disabled), imágenes, bind para eventos extra.
  • Entry: captura de texto, validación en tiempo real, show para contraseñas, maxlength mediante validate.
Ventajas frente a alternativas
WidgetTkinterQt (PySide)WxPython
LabelLigero, sin dependencias externasMás capacidad de estilos CSS‑likeSoporta HTML limitado
ButtonSimple, fácil de enlazar con funcionesSignal‑Slot avanzadoEventos personalizados
EntryValidación con validatecommandQLineEdit con máscarasTextCtrl con estilos

2. Creando un Label con texto personalizado

El widget Label muestra texto o imágenes. Puedes definir fuente, color de fondo, color de texto y alineación.

import tkinter as tk
from tkinter import font

root = tk.Tk()
root.title("Ejemplo de Label")

# Fuente personalizada
mi_fuente = font.Font(family="Helvetica", size=14, weight="bold")

lbl = tk.Label(
    root,
    text="¡Hola, Tkinter!",
    font=mi_fuente,
    fg="#ffffff",          # color del texto
    bg="#007acc",          # color de fondo
    padx=10, pady=5,
    relief="groove"
)
lbl.pack(pady=20)

root.mainloop()

Consejo de seguridad: nunca inserte texto sin escaparlo si proviene de usuarios externos; use html.escape antes de asignarlo a un Label que muestre HTML (cuando se usa tkinterhtml).

3. Un Button que ejecuta una función al hacer clic

Los botones pueden estar vinculados a cualquier función Python mediante el parámetro command. También puedes usar bind para capturar eventos como <Enter> o <Double-Button-1>.

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()
root.title("Botón con acción")

def saludar():
    nombre = entry_nombre.get()
    if not nombre:
        messagebox.showwarning("Entrada vacía", "Escribe tu nombre antes de saludar.")
        return
    messagebox.showinfo("Saludo", f"¡Hola, {nombre}!")

# Entrada para capturar el nombre (ver sección 4)
entry_nombre = tk.Entry(root, width=30)
entry_nombre.pack(pady=10)

btn = tk.Button(
    root,
    text="Saludar",
    command=saludar,
    bg="#28a745",
    fg="#ffffff",
    activebackground="#218838",
    font=("Arial", 12, "bold"),
    padx=12, pady=6,
    cursor="hand2"
)
btn.pack(pady=5)

root.mainloop()

Mejores prácticas: siempre usa command=función sin paréntesis. Si necesitas pasar argumentos, usa lambda o functools.partial para evitar la ejecución inmediata.

4. Capturando texto con Entry y validación en tiempo real

El widget Entry permite al usuario introducir una cadena. Con la opción validate='key' y una función de validación puedes restringir la entrada (por ejemplo, solo números).

import tkinter as tk

root = tk.Tk()
root.title("Entry con validación")

def validar_numeros(P):
    """Devuelve True si P es cadena vacía o solo contiene dígitos"""
    return P.isdigit() or P == ""

vcmd = (root.register(validar_numeros), "%P")

entry_num = tk.Entry(
    root,
    validate="key",
    validatecommand=vcmd,
    font=("Consolas", 12),
    width=20,
    bg="#f8f9fa",
    fg="#212529"
)
entry_num.pack(pady=15)

lbl_res = tk.Label(root, text="Introduce solo números", font=("Helvetica", 10))
lbl_res.pack()

root.mainloop()

En la función de validación, %P representa el contenido propuesto del Entry. Si la función devuelve False, la tecla es ignorada.

Depuración: si la validación no funciona, verifica que root.register() se haya llamado antes de crear el widget y que la tupla (func, "%P") sea la que se pasa a validatecommand.

5. Personalización avanzada con ttk (Themed Tk)

Para interfaces más modernas, usa ttk que soporta temas y estilos CSS‑like. A continuación, un mini‑ejemplo que aplica un tema oscuro y modifica la apariencia de Button y Entry:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title("Tema oscuro con ttk")

style = ttk.Style()
style.theme_use('clam')  # Cambia a un tema base modificable

# Definir colores
bg = "#2d2d2d"
fg = "#f0f0f0"
style.configure('TLabel', background=bg, foreground=fg, font=('Segoe UI', 11))
style.configure('TButton', background="#4a90e2", foreground=fg, font=('Segoe UI', 10, 'bold'))
style.map('TButton', background=[('active', '#357ab8')])
style.configure('TEntry', fieldbackground="#3c3c3c", foreground=fg, font=('Consolas', 10))

root.configure(background=bg)

lbl = ttk.Label(root, text="Etiqueta con tema oscuro")
lbl.pack(pady=10)

entry = ttk.Entry(root, width=30)
entry.pack(pady=5)

btn = ttk.Button(root, text="Aceptar")
btn.pack(pady=10)

root.mainloop()

Usar ttk permite cambiar la apariencia sin tocar cada widget individualmente, lo que mejora la mantenibilidad y la consistencia visual.

6. Buenas prácticas y trucos de troubleshooting

  • Separar lógica y UI: coloca la lógica de negocio en funciones o clases separadas; los callbacks de los botones deben ser ligeros y delegar a esas capas.
  • Gestión de geometría: usa grid para formularios y pack para disposiciones simples. Evita mezclar ambos en el mismo contenedor.
  • Escalado en alta DPI: llama a root.tk.call('tk', 'scaling', factor) para ajustar el factor de escala en pantallas Retina.
  • Depuración de eventos: imprime event.type y event.widget dentro de una función bind para entender el flujo.
  • Seguridad de datos sensibles: si usas Entry para contraseñas, define show='*' y nunca guardes la cadena en texto plano; utiliza keyring o hashing.

© 2025 TuNombre — Tutoriales de Python y GUI con Tkinter. Todos los derechos reservados.