# Botón

> El botón con tema: variantes, tamaños, iconos y atajos. 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/button/

:::tip[En pocas palabras]
Un botón es algo que pulsas para que la app haga algo: guardar, enviar, abrir, borrar.
:::

Muestra un botón con el estilo del tema. Toma los colores del tema actual, puede llevar un icono y un atajo de teclado, y tiene varias variantes y tamaños. Cualquier parámetro de estilo de `pz.button` (`bg`, `hover_bg`, `color`, `shadow`, `radius`…) reemplaza al del tema.

`ui.button` · Categoría: [Acciones](https://albakore.github.io/pyzed/es/library/#acciones) · [Referencia completa →](https://albakore.github.io/pyzed/es/reference/ui/#button)

**Código:**

```python
pz.row([
    ui.button("Cancel", on_cancel, variant="ghost"),
    ui.button("Save", on_save, icon="save", variant="solid", keys="ctrl-s"),
], spacing=8)
```

## Cuándo usarlo

- Para las acciones principales de un formulario, diálogo o barra.
- Usa `variant="solid"` para la acción principal y `"ghost"` para las secundarias.
- Para un botón con solo un icono, usa [Botón de icono](https://albakore.github.io/pyzed/es/library/icon-button/).

## Uso

```python
import pyzed as pz
from pyzed import ui

class Editor(pz.App):
    def save(self):
        ...

    def view(self):
        return ui.button("Save", self.save, icon="save", keys="ctrl-s")
```

## 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.
:::

### Variante

`filled` es la de por defecto; usa `solid` para la única acción principal de una pantalla.

```python
ui.button("Filled", on_press)
```

```python
ui.button("Ghost", on_press, variant="ghost")
```

```python
ui.button("Subtle", on_press, variant="subtle")
```

```python
ui.button("Outline", on_press, variant="outline")
```

```python
ui.button("Solid", on_press, variant="solid")
```

```python
ui.button("Tinted", on_press, variant="tinted")
```

### Colores semánticos

Un nombre de color como `variant` da un botón teñido; `tint=` colorea uno `solid`.

```python
ui.button("Upgrade", on_press, variant="accent", icon="sparkles")
```

```python
ui.button("Done", on_press, variant="success", icon="check")
```

```python
ui.button("Careful", on_press, variant="warning", icon="triangle-alert")
```

```python
ui.button("Delete", on_press, variant="error", icon="trash-2")
```

```python
ui.button("Details", on_press, variant="info", icon="info")
```

```python
ui.button("Delete forever", on_press, variant="solid", tint="error")
```

### Tamaño

```python
ui.button("Extra small", on_press, size="xs")
```

```python
ui.button("Small", on_press, size="sm")
```

```python
ui.button("Medium", on_press, size="md")
```

```python
ui.button("Large", on_press, size="lg")
```

### Contenido

```python
ui.button("Save", on_press, icon="save")
```

```python
ui.button("Next", on_press, icon="arrow-right", icon_position="end")
```

```python
ui.button("Save", on_press, icon="save", keys="ctrl-s")
```

```python
ui.button("Online", on_press, icon="circle", icon_color="success")
```

```python
ui.button(icon="plus", on_press=on_press)
```

### Estado

Un botón sin `on_press` se dibuja deshabilitado, así las acciones sin terminar lo parecen.

```python
ui.button("Selected", on_press, selected=True)
```

```python
ui.button("Disabled", on_press, disabled=True)
```

```python
ui.button("Not wired yet")
```

```python
pz.container(ui.button("Sign in", on_press, variant="solid", full_width=True), width=280)
```

### Estilo propio

Los argumentos de estilo de `pz.button` (`bg`, `hover_bg`, `pressed_bg`, `color`, `border_color`, `shadow`, `radius`, `padding`) reemplazan los valores del tema solo en ese botón.

```python
ui.button("Lifted", on_press, variant="solid", shadow=("#00000066", (0, 4), 12))
```

```python
ui.button("Custom", on_press, bg="#c678dd", hover_bg="#d08ae6", color="#ffffff")
```

```python
ui.button("Gold border", on_press, variant="outline", border_color="#e5c07b")
```

```python
ui.button("Pill", on_press, variant="solid", radius=999)
```

### Estados y eventos

```python
ui.button("Saving", on_press, icon="save", loading=True)
```

```python
ui.button("Save", on_press, tooltip="Writes the file")
```

### Widget base

El widget `pz.*` de debajo: sin tema, todos los colores y tamaños son tuyos.

```python
pz.button("pz.button", on_press, padding=(6, 14), bg="#3a7bc8", color="#ffffff", radius=6)
```

```python
pz.button(pz.row([pz.icon("heart", size=14), pz.text("Like")], spacing=6, align="center"), on_press,
          padding=(6, 12), bg="#c678dd22", color="#c678dd", border_color="#c678dd", border_width=1, radius=999)
```

## Ejemplos

### Ancho completo

`full_width=True` estira el botón hasta el ancho de su contenedor.

**Código:**

```python
pz.column([
    ui.button("Sign in", on_press, variant="solid", full_width=True),
    ui.button("Create an account", on_press, variant="outline", full_width=True),
], spacing=8, width=320)
```

## Eventos

Botón 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 | De | El handler recibe | Cuándo |
| --- | --- | --- | --- |
| `on_press` | `ui.button`, `pz.button` | `()` | 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 Editor(pz.App):
    def __init__(self):
        self.saved = 0

    def save(self):                      # on_press: called with nothing
        self.saved += 1

    def view(self):
        return pz.row([
            ui.button("Save", self.save, icon="save", variant="solid", keys="ctrl-s"),
            ui.button("Reset", lambda: setattr(self, "saved", 0), variant="ghost"),
            ui.label(f"Saved {self.saved} times"),
        ], spacing=8, align="center")
```

**Declarativo:**

```python
class Editor(pz.App):
    saved = 0

    def update(self, message):           # every button sends a message here
        match message:
            case "save":
                self.saved += 1
            case "reset":
                self.saved = 0

    def view(self):
        return pz.row([
            ui.button("Save", "save", icon="save", variant="solid", keys="ctrl-s"),
            ui.button("Reset", "reset", variant="ghost"),
            ui.label(f"Saved {self.saved} times"),
        ], spacing=8, align="center")
```

**Funcional:**

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class State:
    saved: int = 0

def view(state, set_state):              # a pure function: state in, widgets out
    return pz.row([
        ui.button("Save", lambda: set_state(saved=state.saved + 1), icon="save", variant="solid"),
        ui.button("Reset", lambda: set_state(saved=0), variant="ghost"),
        ui.label(f"Saved {state.saved} times"),
    ], spacing=8, align="center")
```

## Consejos

:::tip
Para pasarle un valor al callback, átalo con un argumento por defecto: `ui.button(nombre, lambda n=nombre: self.abrir(n))`.
:::

## Propiedades y API

### `ui.button`

```python
button(
    content=None,
    on_press=None,
    *,
    icon=None,
    icon_position='start',
    icon_color=None,
    variant='filled',
    tint=None,
    size='md',
    selected=False,
    disabled=False,
    full_width=False,
    keys=None,
    loading=False,
    tooltip=None,
    theme=None,
    **style,
)
```

Un botón con tema, con variantes, tamaños, un icono y un atajo.

| Propiedad | Por defecto | Descripción |
| --- | --- | --- |
| `content` | `None` | Texto o widget. |
| `icon` | `None` | Nombre de un icono de Lucide (`pyzed icons` los lista). |
| `icon_position` | `"start"` | `"start"` o `"end"`. |
| `icon_color` | `None` | Color del icono: un token del tema o un color hex. |
| `variant` | `"filled"` | `"filled"`, `"ghost"`, `"subtle"`, `"outline"`, `"solid"`, `"tinted"`, o un color semántico: `"accent"`, `"error"`, `"warning"`, `"success"`, `"info"`. |
| `tint` | `None` | Color de las variantes `solid` y `tinted`. |
| `size` | `"md"` | `"xs"`, `"sm"`, `"md"` o `"lg"`. |
| `selected` | `False` | Lo marca como seleccionado. |
| `disabled` | `False` | Lo deshabilita (ignora los clics). |
| `full_width` | `False` | Ocupa todo el ancho. |
| `keys` | `None` | Atajo que se muestra al final, escrito como texto: `"ctrl-s"`, `"cmd-k cmd-s"`. |
| `loading` | `False` | Muestra un spinner en lugar del icono e ignora las pulsaciones (mantén una suscripción `pz.every(1/30, ...)` mientras gira). |
| `tooltip` | `None` | Texto que aparece al pasar el ratón. |
| `theme` | `None` | Tema a usar en lugar del actual (`pyzed.theme.current()`). |
| `**style` | — | Cualquier parámetro de estilo de `pyzed.button` (`bg`, `hover_bg`, `color`…). |

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

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

### `pz.button`

```python
button(
    content,
    on_press=None,
    *,
    padding=None,
    width=None,
    height=None,
    bg=None,
    color=None,
    border_color=None,
    border_width=0.0,
    radius=None,
    shadow=None,
    hover_bg=None,
    hover_color=None,
    hover_border_color=None,
    pressed_bg=None,
    disabled_color=None,
    clip=False,
)
```

Un botón sin estilo predefinido. Para el botón con tema usa `ui.button`.

| Propiedad | Por defecto | Descripción |
| --- | --- | --- |
| `content` | *obligatorio* | Contenido del botón. |
| `padding` | `None` | Relleno interior: `8`, `(vertical, horizontal)` o `(arriba, derecha, abajo, izquierda)`. |
| `width` | `None` | Ancho: píxeles, `"fill"`, `"shrink"` o `"fill:N"` (proporción). |
| `height` | `None` | Alto: píxeles, `"fill"`, `"shrink"` o `"fill:N"` (proporción). |
| `bg` | `None` | Color de fondo (`"#rrggbb[aa]"`, `(r, g, b[, a])` o `"transparent"`). |
| `color` | `None` | Color del texto o del icono. |
| `border_color` | `None` | Color del borde. |
| `border_width` | `0.0` | Grosor del borde en píxeles. |
| `radius` | `None` | Radio de las esquinas: un número o `(sup_izq, sup_der, inf_der, inf_izq)`. |
| `shadow` | `None` | Sombra: `(color, (dx, dy), desenfoque)`. |
| `hover_bg` | `None` | Fondo al pasar el ratón. |
| `hover_color` | `None` | Color del texto al pasar el ratón. |
| `hover_border_color` | `None` | Color del borde al pasar el ratón. |
| `pressed_bg` | `None` | Fondo mientras se pulsa. |
| `disabled_color` | `None` | Color del texto cuando está deshabilitado. |
| `clip` | `False` | Recorta el contenido que se sale de los límites. |

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

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

## Relacionados

- [Botón de icono](https://albakore.github.io/pyzed/es/library/icon-button/): Un botón cuadrado con solo un icono y un tooltip opcional.
- [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.
- [Grupo de alternancia](https://albakore.github.io/pyzed/es/library/toggle-group/): Un control segmentado solo con iconos.
- [Tooltip](https://albakore.github.io/pyzed/es/library/tooltip/): Una pista que aparece al pasar el ratón, con su atajo opcional.
