Ir al contenido

IDEAS PRÁCTICAS · ASIMOV INGENIERÍA

Organizando tu GUI: Frame, Checkbutton y Radiobutton

Aprende a estructurar interfaces Tkinter con Frame y a usar Checkbutton y Radiobutton mediante variables de control (IntVar, BooleanVar, StringVar). Incluye un ejemplo completo y consejos de buenas prácticas.

Imagen ilustrativa · Fotis Fotopoulos / Unsplash.

Table of contents

No titles in the blog post

Organizando tu GUI: Frame, Checkbutton y Radiobutton

¿Qué es un Frame?

Un Frame es simplemente un contenedor que agrupa widgets dentro de una ventana Tk. Sirve para:

Dos personas trabajando con código en una oficina
Imagen ilustrativa · Compagnons / Unsplash.
  • Dividir la interfaz en áreas lógicas (p.ej. panel de opciones vs panel de resultados).
  • Aplicar estilos o layout managers diferentes en cada zona.
  • Facilitar el mantenimiento y la reutilización de código.

En términos de Bootstrap, equivale a una .card o a una columna de la cuadrícula.

Variables de control

Tkinter usa objetos especiales para almacenar el estado de los widgets interactivos. Los más comunes son:

  • IntVar: almacena valores enteros (0/1 para Checkbutton, índices para Radiobutton).
  • BooleanVar: similar a IntVar pero semánticamente representa True/False.
  • StringVar: guarda texto, útil cuando el valor del Radiobutton es una cadena.

Estas variables permiten que varios widgets compartan el mismo estado y que el programa lea o modifique dicho estado de forma reactiva.

Checkbutton

Un Checkbutton representa una opción binaria (activada/desactivada). Se enlaza a una variable (IntVar o BooleanVar) mediante el argumento variable=.

Ejemplo de uso típico:

show_title = BooleanVar(value=True)
Checkbutton(frame, text="Mostrar título", variable=show_title)

Radiobutton

Los Radiobutton forman un grupo de opciones mutuamente excluyentes. Todos comparten la misma variable; cada botón define su propio value.

Ejemplo con StringVar:

color = StringVar(value="rojo")
Radiobutton(frame, text="Rojo",  variable=color, value="rojo")
Radiobutton(frame, text="Verde", variable=color, value="verde")

Ejemplo práctico

El siguiente script muestra cómo combinar Frame, Checkbutton y Radiobutton. El usuario selecciona varias opciones y, al pulsar Actualizar, el Label muestra el estado actual.

import tkinter as tk
from tkinter import ttk

# ------------------------------------------------------------------
# 1️⃣  Configuración de la ventana principal
# ------------------------------------------------------------------
root = tk.Tk()
root.title("Demo: Frame + Checkbutton + Radiobutton")
root.geometry("500x300")

# ------------------------------------------------------------------
# 2️⃣  Variables de control
# ------------------------------------------------------------------
show_name   = tk.BooleanVar(value=True)   # Checkbutton
show_email  = tk.BooleanVar(value=False)  # Checkbutton
theme_color = tk.StringVar(value="azul") # Radiobutton

# ------------------------------------------------------------------
# 3️⃣  Frame contenedor de los controles
# ------------------------------------------------------------------
control_frame = ttk.LabelFrame(root, text="Opciones")
control_frame.pack(fill="both", expand=True, padx=15, pady=15)

# Checkbuttons ------------------------------------------------------
ck_name  = ttk.Checkbutton(control_frame, text="Mostrar nombre", variable=show_name)
ck_email = ttk.Checkbutton(control_frame, text="Mostrar email", variable=show_email)
ck_name.grid(row=0, column=0, sticky="w", padx=5, pady=5)
ck_email.grid(row=1, column=0, sticky="w", padx=5, pady=5)

# Radiobuttons ------------------------------------------------------
colors = ["azul", "verde", "rojo"]
for idx, col in enumerate(colors):
    rb = ttk.Radiobutton(
        control_frame,
        text=col.capitalize(),
        variable=theme_color,
        value=col
    )
    rb.grid(row=0, column=idx+1, padx=5, pady=5)

# ------------------------------------------------------------------
# 4️⃣  Área de salida (Label) y botón de actualización
# ------------------------------------------------------------------
output_label = ttk.Label(root, text="", anchor="center", font=("Helvetica", 12))
output_label.pack(fill="x", padx=15, pady=10)

def actualizar():
    """Construye una cadena con el estado actual y la muestra en el label."""
    partes = []
    if show_name.get():
        partes.append("Nombre")
    if show_email.get():
        partes.append("Email")
    # Siempre mostramos el color seleccionado
    partes.append(f"Tema: {theme_color.get().capitalize()}")
    output_label.config(text=", ".join(partes))

btn_update = ttk.Button(root, text="Actualizar", command=actualizar)
btn_update.pack(pady=5)

# Iniciamos la GUI
root.mainloop()

Explicación de los puntos clave:

  • LabelFrame actúa como Frame con título.
  • Las variables se crean antes de los widgets para que puedan ser compartidas.
  • Se usa grid dentro del frame para alinear los controles.
  • La función actualizar lee los valores de BooleanVar y StringVar y actualiza el Label.

Buenas prácticas y solución de problemas

  • Separar lógica y presentación: mantén la creación de widgets en una función o clase y la lógica de negocio en otra.
  • Inicializar variables con valor por defecto: evita estados None inesperados.
  • Usar ttk en lugar de los widgets clásicos: ofrecen una apariencia nativa y son más fáciles de tematizar.
  • Depuración: imprime el valor de las variables con print(var.get()) dentro de la callback para validar su contenido.
  • Accesibilidad: asigna focus() al primer control y usa Alt+Key en el texto del botón para usuarios de teclado.