Ir al contenido

IDEAS PRÁCTICAS · ASIMOV INGENIERÍA

9 Crear menús profesionales en Tkinter (File, Edit, Help…) – Guía completa

Aprende paso a paso a crear barras de menú en Tkinter con submenús típicos (Archivo, Edición, Ayuda), atajos de teclado, separadores y buenas prácticas. Incluye ejemplo completo y comparativas con otras librerías GUI.

Imagen ilustrativa · Emile Perron / Unsplash.

Table of contents

No titles in the blog post

Introducción

Tkinter es la biblioteca estándar de interfaces gráficas en Python. Una barra de menú bien estructurada mejora la usabilidad y le da a tu aplicación un aspecto profesional. En este artículo veremos cómo:

Pantalla con un editor de código
Imagen ilustrativa · Chris Ried / Unsplash.
  • Crear la barra de Menu y sus sub‑menús (Archivo, Edición, Ayuda).
  • Asociar funciones a cada ítem y usar separadores.
  • Definir atajos de teclado (por ejemplo Ctrl+N y Ctrl+S).
  • Aplicar buenas prácticas de mantenimiento, compatibilidad y rendimiento.

1. Estructura básica del menú

El widget Menu se ancla a la ventana principal mediante el método config(menu=menu_bar). Cada sub‑menú es a su vez un Menu con la opción tearoff=0 para evitar la línea de separación “desprendible”.

import tkinter as tk

root = tk.Tk()
root.title("Ejemplo de menú")

# Barra de menú principal
menu_bar = tk.Menu(root)
root.config(menu=menu_bar)

2. Sub‑menú Archivo con separadores y atajos

Los atajos se añaden mediante la opción accelerator (solo visual) y vinculando la combinación con bind_all o bind_class para que funcione en cualquier widget.

def nuevo():
    print("Nuevo documento")

def abrir():
    print("Abrir archivo")

def guardar():
    print("Guardar archivo")

def salir():
    root.quit()

file_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Archivo", menu=file_menu)

file_menu.add_command(label="Nuevo", accelerator="Ctrl+N", command=nuevo)
file_menu.add_command(label="Abrir…", accelerator="Ctrl+O", command=abrir)
file_menu.add_separator()
file_menu.add_command(label="Guardar", accelerator="Ctrl+S", command=guardar)
file_menu.add_separator()
file_menu.add_command(label="Salir", accelerator="Alt+F4", command=salir)

# Vinculación de atajos
root.bind_all("", lambda e: nuevo())
root.bind_all("", lambda e: abrir())
root.bind_all("", lambda e: guardar())
root.bind_all("", lambda e: salir())

3. Sub‑menú Edición (opcional)

En aplicaciones más complejas se añaden comandos como Cortar, Copiar y Pegar. Tkinter ya incluye atajos por defecto, pero podemos reforzarlos.

edit_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Edición", menu=edit_menu)

edit_menu.add_command(label="Cortar", accelerator="Ctrl+X", command=lambda: root.focus_get().event_generate('<>'))
edit_menu.add_command(label="Copiar", accelerator="Ctrl+C", command=lambda: root.focus_get().event_generate('<>'))
edit_menu.add_command(label="Pegar", accelerator="Ctrl+V", command=lambda: root.focus_get().event_generate('<>'))

root.bind_all('', lambda e: root.focus_get().event_generate('<>'))
root.bind_all('', lambda e: root.focus_get().event_generate('<>'))
root.bind_all('', lambda e: root.focus_get().event_generate('<>'))

4. Sub‑menú Ayuda con enlaces externos

Los ítems de ayuda suelen abrir diálogos o lanzar el navegador web.

import webbrowser

def mostrar_acerca():
    tk.messagebox.showinfo("Acerca de", "Aplicación demo – Tkinter 2025")

def abrir_documentacion():
    webbrowser.open_new_tab('https://docs.python.org/3/library/tkinter.html')

help_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Ayuda", menu=help_menu)

help_menu.add_command(label="Documentación", command=abrir_documentacion)
help_menu.add_separator()
help_menu.add_command(label="Acerca de…", command=mostrar_acerca)

5. Buenas prácticas y consideraciones avanzadas

Compatibilidad y estilos
  • En macOS, los menús aparecen en la barra del sistema. Usa root.createcommand si necesitas adaptar atajos.
  • Para un look native en Windows, evita ttk.Style en los menús; Tkinter ya respeta el tema del SO.
  • Si la aplicación será empaquetada con PyInstaller, verifica que los recursos (iconos, archivos .ico) estén incluidos en el spec.
Rendimiento y escalabilidad
  • Los menús se crean una sola vez; evita recrearlos en callbacks para reducir overhead.
  • En interfaces con cientos de comandos, considera lazy loading (cargar sub‑menús al abrirlos).
  • Utiliza menu.entryconfig(index, state='disabled') para desactivar temporalmente opciones costosas.

6. Solución de problemas frecuente

  • Los atajos no funcionan en algunos widgets. Asegúrate de usar bind_all o bind_class('Text') según el widget objetivo.
  • Separadores aparecen como líneas gruesas. En versiones antiguas de Tk, el estilo se controla con la variable de entorno TCL_LIBRARY. Actualiza a Tk 8.6+.
  • El menú desaparece al maximizar la ventana. Verifica que no estés llamando a root.geometry() después de config(menu=…).

7. Ejemplo completo listo para ejecutar

import tkinter as tk
from tkinter import messagebox
import webbrowser

# ---------------------------------------------------
# Funciones de los ítems del menú
# ---------------------------------------------------
def nuevo():
    messagebox.showinfo("Nuevo", "Crear un nuevo documento")

def abrir():
    messagebox.showinfo("Abrir", "Abrir archivo existente")

def guardar():
    messagebox.showinfo("Guardar", "Guardar documento actual")

def salir():
    root.quit()

def mostrar_acerca():
    messagebox.showinfo("Acerca de", "Demo de menús con Tkinter – 2025")

def abrir_documentacion():
    webbrowser.open_new_tab('https://docs.python.org/3/library/tkinter.html')

# ---------------------------------------------------
# Configuración de la ventana principal
# ---------------------------------------------------
root = tk.Tk()
root.title("Demo de barra de menú")
root.geometry("500x300")

# ---------------------------------------------------
# Creación de la barra de menú
# ---------------------------------------------------
menu_bar = tk.Menu(root)
root.config(menu=menu_bar)

# Archivo
file_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Archivo", menu=file_menu)
file_menu.add_command(label="Nuevo", accelerator="Ctrl+N", command=nuevo)
file_menu.add_command(label="Abrir…", accelerator="Ctrl+O", command=abrir)
file_menu.add_separator()
file_menu.add_command(label="Guardar", accelerator="Ctrl+S", command=guardar)
file_menu.add_separator()
file_menu.add_command(label="Salir", accelerator="Alt+F4", command=salir)

# Edición (opcional)
edit_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Edición", menu=edit_menu)
edit_menu.add_command(label="Cortar", accelerator="Ctrl+X", command=lambda: root.focus_get().event_generate('<>'))
edit_menu.add_command(label="Copiar", accelerator="Ctrl+C", command=lambda: root.focus_get().event_generate('<>'))
edit_menu.add_command(label="Pegar", accelerator="Ctrl+V", command=lambda: root.focus_get().event_generate('<>'))

# Ayuda
help_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Ayuda", menu=help_menu)
help_menu.add_command(label="Documentación", command=abrir_documentacion)
help_menu.add_separator()
help_menu.add_command(label="Acerca de…", command=mostrar_acerca)

# ---------------------------------------------------
# Atajos de teclado (globales)
# ---------------------------------------------------
root.bind_all('', lambda e: nuevo())
root.bind_all('', lambda e: abrir())
root.bind_all('', lambda e: guardar())
root.bind_all('', lambda e: salir())
root.bind_all('', lambda e: root.focus_get().event_generate('<>'))
root.bind_all('', lambda e: root.focus_get().event_generate('<>'))
root.bind_all('', lambda e: root.focus_get().event_generate('<>'))

# ---------------------------------------------------
# Main loop
# ---------------------------------------------------
root.mainloop()

Ejecuta este script y observa cómo los menús y los atajos funcionan en Windows, macOS y Linux sin cambios.

© 2025 TuNombre – Expertos en Python y GUI. Todos los derechos reservados.