DMarlon Studio

Lección 10 · 10 de 20

Menú contextual y botones de menú · tkinter

Abra un menú con el botón derecho en tkinter (tk_popup) y use ttk.Menubutton y tk.OptionMenu para elegir opciones dentro de la ventana.

tkinter · Menú contextual y botones de menú en DMarlon Studio: el código del ejemplo y la ventana que abre al ejecutarlo

Un menú contextual es un tk.Menu normal que no se pone en la barra: se muestra donde está el ratón con tk_popup(x, y). Las coordenadas e.x_root y e.y_root del evento son de la pantalla, que es lo que pide tk_popup.

Se abre al pulsar el botón derecho sobre el recuadro. Ese botón es <Button-3> en Windows, en Linux y en el Tk actual de macOS, pero en versiones antiguas de Tk para macOS era <Button-2>; enlazar los dos lo cubre todo. Cada opción llama a do, que escribe la última acción en la etiqueta de abajo.

ttk.Menubutton es un botón que despliega su propio menú: el menú se crea con el botón como padre y se le asigna con export["menu"] = formats. Va bien para grupos de acciones, como exportar a PDF, CSV o Excel.

tk.OptionMenu(padre, variable, opción1, opción2, ...) es un botón que enseña la opción elegida y la guarda en una StringVar; command= recibe el valor nuevo cada vez que cambia. Se parece a un ttk.Combobox de solo lectura, pero con un menú.

En DMarlon Studio, los componentes tienen el evento Clic derecho en la pestaña Eventos del inspector (el estudio lo enlaza a <Button-2> y <Button-3>); desde ese método puede abrir un menú contextual con tk_popup, como aquí.

Código · main.py

import tkinter as tkfrom tkinter import ttkroot = tk.Tk()root.title("Menus inside the window")root.geometry("460x250")last = tk.StringVar(value="Last action: Copy")do = lambda action: last.set(f"Last action: {action}")# A context menu: a Menu outside the bar, shown with tk_popup(x, y).popup = tk.Menu(root, tearoff=0)for action in ("Cut", "Copy", "Paste", "Select all"):    popup.add_command(label=action, command=lambda a=action: do(a))area = tk.Label(root, text="Right-click here", bg="white", fg="gray", relief="solid", bd=1)area.pack(fill="x", padx=20, pady=20, ipady=30)for click in ("<Button-3>", "<Button-2>"):  # right button (Button-2: older Tk on macOS)    area.bind(click, lambda e: popup.tk_popup(e.x_root, e.y_root))# Menubutton: a button that drops down its own Menu.row = ttk.Frame(root)row.pack()export = ttk.Menubutton(row, text="Export")formats = tk.Menu(export, tearoff=0)for fmt in ("PDF", "CSV", "Excel"):    formats.add_command(label=fmt, command=lambda f=fmt: do(f"Export as {f}"))export["menu"] = formatsexport.pack(side="left", padx=10)# OptionMenu: shows the chosen value of a list and keeps it in a variable.size = tk.StringVar(value="Medium")tk.OptionMenu(row, size, "Small", "Medium", "Large", command=lambda v: do(f"Size {v}")).pack(side="left")ttk.Label(root, textvariable=last).pack(pady=18)root.mainloop()

Para recordar

  • tk_popup(x_root, y_root) abre un menú donde está el ratón.
  • Enlace <Button-3> y <Button-2> para el botón derecho.
  • ttk.Menubutton despliega su propio menú.
  • tk.OptionMenu guarda la opción elegida en una variable.

Ejercicio

Añada al menú contextual un separador y la opción «Clear», que deje la etiqueta en «Last action: none»; y añada «Huge» al OptionMenu.