# Grupo de radios

> Opciones excluyentes como botones de radio. 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/radio-group/

:::tip[En pocas palabras]
Unas cuantas opciones redondas en las que elegir una desmarca las demás.
:::

Un conjunto de botones de radio con una opción elegida. `options` son cadenas o pares `(valor, etiqueta)`; `on_select` recibe el valor. `horizontal=True` los coloca en fila.

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

**Código:**

```python
pz.row([
    ui.radio_group(["Spaces", "Tabs"], "Spaces", on_select),
    ui.radio_group([("lf", "LF"), ("crlf", "CRLF"), ("cr", "CR")], "lf", on_select, horizontal=True),
], spacing=40, align="center")
```

## Cuándo usarlo

- Cuando cada opción necesita su etiqueta y conviene verlas todas (indentación: espacios o tabuladores).
- Para muchas opciones usa un [Select](https://albakore.github.io/pyzed/es/library/select/).

## Uso

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

class Settings(pz.App):
    def __init__(self):
        self.indent = "spaces"

    def view(self):
        return ui.radio_group([("spaces", "Spaces"), ("tabs", "Tabs")], self.indent,
                              lambda value: setattr(self, "indent", value))
```

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

### Dirección

```python
ui.radio_group(["Spaces", "Tabs"], "Spaces", on_select)
```

```python
ui.radio_group(["LF", "CRLF", "CR"], "LF", on_select, horizontal=True)
```

```python
ui.radio_group(["Small", "Medium", "Large"], "Medium", on_select, horizontal=True, spacing=16)
```

### Opciones

```python
ui.radio_group([("lf", "Unix (LF)"), ("crlf", "Windows (CRLF)")], "crlf", on_select)
```

```python
ui.radio_group(["Yes", "No"], None, on_select, horizontal=True)
```

### Estados y eventos

```python
ui.radio_group(["LF", "CRLF", "CR"], "LF", on_select, horizontal=True, disabled={"CR"})
```

```python
ui.radio_group(["Spaces", "Tabs"], "Spaces", on_select,
               descriptions={"Spaces": "Indent with 4 spaces", "Tabs": "One tab per level"})
```

### Widget base

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

```python
pz.row([pz.radio("Cats", True, on_select, accent="#e5c07b"),
        pz.radio("Dogs", False, on_select, accent="#e5c07b")], spacing=16)
```

## Eventos

Grupo de radios 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_select` | `ui.radio_group`, `pz.radio` | `(value)` | Callable que recibe el valor elegido. |

**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 Settings(pz.App):
    def __init__(self):
        self.indent = "spaces"

    def set_indent(self, value):         # on_select gets the value, not the label
        self.indent = value

    def view(self):
        return ui.radio_group([("spaces", "Spaces"), ("tabs", "Tabs")], self.indent, self.set_indent)
```

**Declarativo:**

```python
from dataclasses import dataclass

@dataclass
class Indent:
    value: str

class Settings(pz.App):
    indent = "spaces"

    def update(self, message):
        match message:
            case Indent(value):
                self.indent = value

    def view(self):
        return ui.radio_group([("spaces", "Spaces"), ("tabs", "Tabs")], self.indent, Indent)
```

**Funcional:**

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class State:
    indent: str = "spaces"

def view(state, set_state):
    return ui.radio_group([("spaces", "Spaces"), ("tabs", "Tabs")], state.indent,
                          lambda value: set_state(indent=value), horizontal=True)
```

## Consejos

:::tip
Al pulsarlo o llegar con Tab el grupo tiene el foco del teclado: las flechas eligen la opción anterior o la siguiente (saltando las desactivadas) e Inicio/Fin la primera y la última.
:::

## Propiedades y API

### `ui.radio_group`

```python
radio_group(
    options,
    selected,
    on_select=None,
    *,
    horizontal=False,
    spacing=8,
    disabled=False,
    descriptions=None,
    id=None,
    theme=None,
)
```

Opciones mutuamente excluyentes como botones de radio.

| Propiedad | Por defecto | Descripción |
| --- | --- | --- |
| `options` | *obligatorio* | Textos o pares `(valor, etiqueta)`. |
| `selected` | *obligatorio* | Valor actual. |
| `horizontal` | `False` | En fila en lugar de columna. |
| `spacing` | `8` | Separación entre hijos, en píxeles. |
| `disabled` | `False` | `True`, o los valores a desactivar. |
| `descriptions` | `None` | Asocia valores a una línea atenuada bajo su etiqueta. |
| `id` | `None` | Identificador estable para enfocarlo o desplazarlo con un `Command`. |
| `theme` | `None` | Tema a usar en lugar del actual (`pyzed.theme.current()`). |

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

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

### `pz.radio`

```python
radio(
    label,
    selected,
    on_select=None,
    *,
    size=None,
    text_size=None,
    spacing=None,
    accent=None,
    bg=None,
    border_color=None,
    color=None,
)
```

Un botón de radio. Agrupa varios tú mismo (o usa `ui.radio_group`); `on_select` se envía al pulsarlo.

| Propiedad | Por defecto | Descripción |
| --- | --- | --- |
| `label` | *obligatorio* | Texto de la etiqueta. |
| `selected` | *obligatorio* | Si está marcado. |
| `size` | `None` | Tamaño. |
| `text_size` | `None` | Tamaño del texto. |
| `spacing` | `None` | Separación entre el círculo y el texto. |
| `accent` | `None` | Color de acento (parte activa). |
| `bg` | `None` | Color de fondo (`"#rrggbb[aa]"`, `(r, g, b[, a])` o `"transparent"`). |
| `border_color` | `None` | Color del borde. |
| `color` | `None` | Color del texto o del icono. |

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

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

## Relacionados

- [Segmentado](https://albakore.github.io/pyzed/es/library/segmented/): Un grupo de botones de texto excluyentes.
- [Select](https://albakore.github.io/pyzed/es/library/select/): Un desplegable para elegir una opción.
- [Casilla](https://albakore.github.io/pyzed/es/library/checkbox/): Una casilla de verificación con etiqueta opcional.
