# Menú

> Un menú contextual con iconos, atajos y marcas. Un componente nativo de Pyzed para GUIs de escritorio en Python, con vista previa, ejemplos y su API.

Source: https://albakore.github.io/pyzed/es/library/menu/

:::tip[En pocas palabras]
La lista de opciones que aparece al hacer clic derecho o pulsar un botón de “más”.
:::

Un menú contextual flotante. Las entradas son `ui.MenuItem(label, on_press, icon=, keys=, checked=, danger=, disabled=)`; `ui.SEPARATOR` dibuja una línea entre grupos y una cadena es una cabecera. Muéstralo con un [Popover](https://albakore.github.io/pyzed/es/library/popover/) o una [Capa](https://albakore.github.io/pyzed/es/library/layer/).

`ui.menu` · Categoría: [Listas y menús](https://albakore.github.io/pyzed/es/library/#listas-y-menús) · [Referencia completa →](https://albakore.github.io/pyzed/es/reference/ui/#menu)

**Código:**

```python
ui.menu([
    ui.MenuItem("New file", on_new, icon="file-plus", keys="ctrl-n"),
    ui.MenuItem("New folder", on_new_folder, icon="folder-plus"),
    ui.SEPARATOR,
    "EDIT",
    ui.MenuItem("Copy path", on_copy, keys="ctrl-alt-c"),
    ui.MenuItem("Soft wrap", on_wrap, checked=True),
    ui.SEPARATOR,
    ui.MenuItem("Delete", on_delete, icon="trash-2", danger=True),
])
```

## Cuándo usarlo

- Para menús de clic derecho y las opciones de un botón dividido o de puntos suspensivos.
- Marca las acciones destructivas con `danger=True` y ponlas al final.

## Uso

```python
from pyzed import ui

ui.menu([
    ui.MenuItem("New file", on_new, icon="file-plus", keys="ctrl-n"),
    ui.MenuItem("New folder", on_new_folder, icon="folder-plus"),
    ui.SEPARATOR,
    "EDIT",
    ui.MenuItem("Copy path", on_copy, keys="ctrl-alt-c"),
    ui.MenuItem("Soft wrap", on_wrap, checked=True),
    ui.SEPARATOR,
    ui.MenuItem("Delete", on_delete, icon="trash-2", danger=True),
])
```

## Variantes

:::note[Sobre estas capturas]
Cada captura la graba pyzed mismo, fuera de pantalla a 2x, en One Dark o One Light según el tema de este sitio, y recortada al componente para que se vea a su tamaño real. El puntero pasa por encima, pulsa o escribe en él; un componente que no reacciona al puntero recorre algunos temas. Con movimiento reducido ves el primer fotograma. Abre **Código** bajo una captura para ver el fragmento que la dibuja; los nombres libres como `on_save` son tus propios callbacks.
:::

### Entradas

```python
ui.menu([ui.MenuItem("Open", on_open), ui.MenuItem("Rename", on_rename),
         ui.MenuItem("Duplicate", on_duplicate)], width=200)
```

```python
ui.menu([ui.MenuItem("Copy", on_copy, icon="copy", keys="ctrl-c"),
         ui.MenuItem("Paste", on_paste, icon="clipboard", keys="ctrl-v")], width=220)
```

```python
ui.menu([ui.MenuItem("Soft wrap", on_wrap, checked=True),
         ui.MenuItem("Minimap", on_minimap, checked=False)], width=200)
```

```python
ui.menu([ui.MenuItem("Rename", on_rename), ui.SEPARATOR,
         ui.MenuItem("Delete", on_delete, icon="trash-2", danger=True)], width=200)
```

```python
ui.menu([ui.MenuItem("Undo", on_undo, keys="ctrl-z"),
         ui.MenuItem("Redo", on_redo, keys="ctrl-shift-z", disabled=True)], width=220)
```

### Grupos

```python
ui.menu(["FILE", ui.MenuItem("New", on_new, keys="ctrl-n"), ui.SEPARATOR,
         "EDIT", ui.MenuItem("Find", on_find, keys="ctrl-f")], width=220)
```

### Estados y eventos

```python
ui.menu([ui.MenuItem("Share", on_press, icon="share", submenu=True),
         ui.MenuItem("Rename", on_press, description="F2 also works")])
```

```python
ui.menu([ui.MenuItem(f"Recent {i}", on_press) for i in range(10)], max_height=140)
```

## Eventos

Menú tiene **1 evento propios**, en la tabla de abajo. Como todo widget, también tiene los **18 eventos comunes** (`click`, `double_click`, `right_click`, `mouse_enter`, `drag`, `key_down`, `resize`…), que se conectan con `.on(...)`: mira [Eventos](https://albakore.github.io/pyzed/es/guides/events/) y [Eventos de cada componente](https://albakore.github.io/pyzed/es/library/events/).

| Evento | El handler recibe | Cuándo |
| --- | --- | --- |
| `on_press` | `()` | Mensaje o callable que se envía al pulsar. `None` deshabilita el control. |

**El handler recibe** es lo que Pyzed le pasa a tu función: `()` es nada. Cualquier handler también puede ser un mensaje (un valor que no se puede llamar), que va a `update()`.

### Manejar los eventos

Los mismos eventos escritos de tres formas. **Imperativa**: métodos de la app que cambian `self`. **Declarativa**: los handlers producen mensajes y un único `update()` decide. **Funcional**: una función pura dibuja un estado inmutable y pide cambios con `set_state(...)`. Mira [Imperativo, declarativo y funcional](https://albakore.github.io/pyzed/es/guides/code-styles/).

**Imperativo:**

```python
class Files(pz.App):
    def __init__(self):
        self.wrap = True
        self.log = []

    def view(self):
        return ui.menu([
            ui.MenuItem("New file", lambda: self.log.append("new"), icon="file-plus", keys="ctrl-n"),
            ui.MenuItem("Soft wrap", lambda: setattr(self, "wrap", not self.wrap), checked=self.wrap),
            ui.SEPARATOR,
            ui.MenuItem("Delete", lambda: self.log.append("delete"), icon="trash-2", danger=True),
        ])
```

**Declarativo:**

```python
class Files(pz.App):
    wrap = True

    def update(self, message):           # each item's on_press is a message
        match message:
            case "new":
                print("new file")
            case "wrap":
                self.wrap = not self.wrap

    def view(self):
        return ui.menu([ui.MenuItem("New file", "new", icon="file-plus", keys="ctrl-n"),
                        ui.MenuItem("Soft wrap", "wrap", checked=self.wrap)])
```

**Funcional:**

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class State:
    wrap: bool = True

def view(state, set_state):
    return ui.menu([
        ui.MenuItem("Soft wrap", lambda: set_state(wrap=not state.wrap), checked=state.wrap),
        ui.MenuItem("Delete", None, icon="trash-2", danger=True, disabled=True),
    ])
```

## Propiedades y API

### `ui.menu`

```python
menu(items, *, width=240, max_height=None, theme=None)
```

Un menú contextual flotante. Usa `ui.SEPARATOR` entre grupos; un texto suelto es un encabezado.

| Propiedad | Por defecto | Descripción |
| --- | --- | --- |
| `items` | *obligatorio* | Lista de `MenuItem`, `ui.SEPARATOR` o textos. |
| `width` | `240` | Ancho: píxeles, `"fill"`, `"shrink"` o `"fill:N"` (proporción). |
| `max_height` | `None` | Desplaza un menú más alto que esto. |
| `theme` | `None` | Tema a usar en lugar del actual (`pyzed.theme.current()`). |

[Referencia completa →](https://albakore.github.io/pyzed/es/reference/ui/#menu)

### `ui.MenuItem`

```python
@dataclass
class MenuItem(label, on_press=None, icon=None, keys=None, disabled=False, danger=False, checked=None, description=None, submenu=False)
```

Una entrada de `ui.menu`.

| Propiedad | Por defecto | Descripción |
| --- | --- | --- |
| `label` | *obligatorio* | Texto de la etiqueta. |
| `icon` | `None` | Nombre de un icono de Lucide (`pyzed icons` los lista). |
| `keys` | `None` | Atajo que se muestra al final, escrito como texto: `"ctrl-s"`, `"cmd-k cmd-s"`. |
| `disabled` | `False` | Lo deshabilita (ignora los clics). |
| `danger` | `False` | En rojo (acciones destructivas). |
| `checked` | `None` | Muestra una marca (`True`/`False`) o nada (`None`). |
| `description` | `None` | Una segunda línea atenuada. |
| `submenu` | `False` | Termina la fila con una flecha; abre el siguiente menú al lado en `on_press`. |

Eventos: `on_press` ([eventos](#eventos)).

[Referencia completa →](https://albakore.github.io/pyzed/es/reference/ui/#menuitem)

### `ui.SEPARATOR`

Separador para `ui.menu`.

[Referencia completa →](https://albakore.github.io/pyzed/es/reference/ui/#separator)

## Relacionados

- [Popover](https://albakore.github.io/pyzed/es/library/popover/): Contenido flotante en un punto: menús contextuales, selectores de color.
- [Botón dividido](https://albakore.github.io/pyzed/es/library/split-button/): Una acción principal más una flecha que abre más opciones.
- [Fila de lista](https://albakore.github.io/pyzed/es/library/list-item/): Una fila de lista con icono, texto y un hueco al final.
