Introducción a Tkinter
Tkinter es el módulo estándar de Python para crear interfaces gráficas de usuario (GUI). Viene incluido en Python, por lo que no necesitás instalar nada.
Con Tkinter podés crear: ventanas, botones, formularios, menús, diálogos, canvas y mucho más.
Necesitás conocer Python Básico e Intermedio (clases, eventos, funciones) antes de trabajar con Tkinter.
Primera Ventana
Toda aplicación Tkinter sigue la misma estructura básica: crear la ventana raíz, agregar widgets y entrar en el bucle principal.
import tkinter as tk
from tkinter import ttk
# 1. Crear la ventana principal
root = tk.Tk()
root.title("Mi Primera App")
root.geometry("400x300") # ancho x alto
root.resizable(True, True) # redimensionable
# 2. Agregar un widget simple
label = tk.Label(root, text="¡Hola desde Tkinter!", font=("Arial", 16))
label.pack(pady=20)
# 3. Iniciar el bucle de eventos (¡siempre al final!)
root.mainloop()
Widgets Básicos
Los widgets son los elementos visuales de la interfaz.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title("Widgets Demo")
root.geometry("480x400")
# ── Label ──────────────────────────
lbl = tk.Label(root, text="Nombre:", font=("Arial", 12))
lbl.pack(pady=5)
# ── Entry (campo de texto) ─────────
entry_nombre = tk.Entry(root, width=30)
entry_nombre.pack(pady=5)
# ── Button ─────────────────────────
def saludar():
nombre = entry_nombre.get()
resultado_lbl.config(text=f"¡Hola, {nombre}!")
btn = tk.Button(root, text="Saludar", command=saludar, bg="#0066ff", fg="white")
btn.pack(pady=10)
# ── CheckButton ────────────────────
var_check = tk.BooleanVar()
check = tk.Checkbutton(root, text="Acepto términos", variable=var_check)
check.pack()
# ── Combobox (lista desplegable) ───
combo = ttk.Combobox(root, values=["Python", "HTML", "JavaScript"])
combo.set("Elegí un lenguaje")
combo.pack(pady=5)
# ── Label para mostrar resultado ───
resultado_lbl = tk.Label(root, text="", font=("Arial", 14), fg="#0066ff")
resultado_lbl.pack(pady=10)
root.mainloop()
Layout Managers
Tkinter tiene tres sistemas para posicionar widgets:
- pack() — posiciona automáticamente en filas/columnas.
- grid() — usa una grilla de filas y columnas (más preciso).
- place() — posición exacta en píxeles (menos flexible).
# Formulario con grid() — el más profesional
root = tk.Tk()
root.title("Formulario de Registro")
root.geometry("350x220")
campos = [("Nombre:", 0), ("Apellido:", 1), ("Email:", 2)]
entries = {}
for texto, fila in campos:
tk.Label(root, text=texto).grid(row=fila, column=0, padx=10, pady=8, sticky="e")
entry = tk.Entry(root, width=25)
entry.grid(row=fila, column=1, padx=10, pady=8)
entries[texto] = entry
def registrar():
datos = {k: v.get() for k, v in entries.items()}
print("Datos registrados:", datos)
tk.Button(root, text="Registrar", command=registrar, bg="#00d264", fg="white", width=15
).grid(row=3, column=0, columnspan=2, pady=15)
root.mainloop()
Eventos y Bindings
Los eventos son acciones del usuario (clic, teclado, movimiento del mouse). Con bind() podemos capturarlos.
import tkinter as tk
root = tk.Tk()
root.title("Eventos")
root.geometry("400x300")
lbl = tk.Label(root, text="Interactuá conmigo", font=("Arial", 14))
lbl.pack(pady=30)
# Evento con teclado
def al_presionar_tecla(evento):
lbl.config(text=f"Presionaste: {evento.char}")
root.bind("<Key>", al_presionar_tecla)
# Enter
root.bind("<Return>", lambda e: lbl.config(text="¡Presionaste Enter!"))
# Double click en el label
lbl.bind("<Double-Button-1>", lambda e: lbl.config(text="¡Doble clic!"))
# Mouse hover
lbl.bind("<Enter>", lambda e: lbl.config(fg="blue"))
lbl.bind("<Leave>", lambda e: lbl.config(fg="black"))
root.mainloop()
Ejercicios Resueltos
Creá una calculadora con dos campos numéricos y botones para las 4 operaciones básicas.
- 1Usamos grid() para organizar los elementos.
- 2Cada botón llama a una función pasando el operador.
- 3Mostramos el resultado con Label.config().
- 4Manejamos divisiones por cero con try/except.
import tkinter as tk
root = tk.Tk()
root.title("Calculadora")
root.geometry("320x220")
root.resizable(False, False)
tk.Label(root, text="Número 1:").grid(row=0, column=0, padx=10, pady=10, sticky="e")
num1 = tk.Entry(root, width=12)
num1.grid(row=0, column=1)
tk.Label(root, text="Número 2:").grid(row=1, column=0, padx=10, pady=10, sticky="e")
num2 = tk.Entry(root, width=12)
num2.grid(row=1, column=1)
resultado = tk.Label(root, text="Resultado: —", font=("Arial", 13), fg="#0066ff")
resultado.grid(row=3, column=0, columnspan=2, pady=15)
def calcular(op):
try:
a = float(num1.get())
b = float(num2.get())
ops = {"+": a+b, "-": a-b, "×": a*b, "÷": a/b}
res = ops[op]
resultado.config(text=f"Resultado: {res:.4g}")
except ZeroDivisionError:
resultado.config(text="Error: ÷ por cero")
except:
resultado.config(text="Error: dato inválido")
frame_btns = tk.Frame(root)
frame_btns.grid(row=2, column=0, columnspan=2, pady=8)
for op in ["+", "-", "×", "÷"]:
tk.Button(frame_btns, text=op, width=5, command=lambda o=op: calcular(o)).pack(side="left", padx=4)
root.mainloop()
Ejercicios Propuestos
Hacé una app que convierta entre Celsius, Fahrenheit y Kelvin.
- Un campo de entrada y 3 botones de conversión.
- Mostrar el resultado en un label formateado.
- Validar que se ingrese un número válido.
Creá una app de lista de tareas con Tkinter.
- Campo para escribir la tarea + botón "Agregar".
- Listbox para mostrar las tareas.
- Botón "Eliminar seleccionada".
- Botón "Limpiar todo".