# Pregunta

> Pide una línea de texto. 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/prompt/

:::tip[En pocas palabras]
Una cajita que te pide escribir algo, como un nombre nuevo para un archivo.
:::

Pide una línea de texto: un campo controlado más Cancelar y Aceptar. Enter o el botón llaman a `on_submit`.

`ui.prompt` · Categoría: [Diálogos](https://albakore.github.io/pyzed/es/library/#diálogos) · [Referencia completa →](https://albakore.github.io/pyzed/es/reference/ui/#prompt)

**Código:**

```python
ui.dialog_layer(main_view(), ui.prompt(
    "Rename", "notes.py", on_input, on_submit, on_cancel,
    message="New name for the file:", width=360,
))
```

:::note[Nuevo]
Este componente se añadió hace poco. Cuéntanos qué tal te funciona en el [gestor de incidencias](https://github.com/albakore/pyzed/issues).
:::

## Cuándo usarlo

- Para nombres rápidos: renombrar un archivo, nombrar una rama, guardar una vista.

## Uso

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

class Files(pz.App):
    def __init__(self):
        self.new_name = None

    def view(self):
        dialog = None
        if self.new_name is not None:
            dialog = ui.prompt("Rename", self.new_name, lambda t: setattr(self, "new_name", t),
                               self.rename, lambda: setattr(self, "new_name", None))
        return ui.dialog_layer(self.main_view(), dialog)
```

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

### Contenido

```python
ui.prompt("New branch", "", on_input, on_submit, on_cancel, placeholder="feature/…", width=340)
```

```python
ui.prompt("Rename", "notes.py", on_input, on_submit, on_cancel, message="New name for the file:",
          width=340)
```

```python
ui.prompt("Save view", "My view", on_input, on_submit, on_cancel, submit_label="Save", width=340)
```

## Eventos

Pregunta tiene **3 eventos 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_input` | `(text)` | Recibe cada edición. |
| `on_submit` | `()` | Enter o el botón de aceptar. |
| `on_cancel` | `()` | Cancelar, el icono de cerrar. |

**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.name = "notes.py"
        self.new_name = "notes.py"       # None while the dialog is closed

    def rename(self):                    # on_submit: Enter or the button
        self.name, self.new_name = self.new_name, None

    def view(self):
        dialog = None
        if self.new_name is not None:
            dialog = ui.prompt("Rename", self.new_name,
                               lambda text: setattr(self, "new_name", text),     # on_input
                               self.rename,
                               lambda: setattr(self, "new_name", None),          # on_cancel
                               message="New name for the file:")
        return ui.dialog_layer(main_view(), dialog)
```

**Declarativo:**

```python
from dataclasses import dataclass

@dataclass
class Typed:
    text: str

class Files(pz.App):
    name, new_name = "notes.py", "notes.py"

    def update(self, message):
        match message:
            case Typed(text):
                self.new_name = text
            case "rename":
                self.name, self.new_name = self.new_name, None
            case "cancel":
                self.new_name = None

    def view(self):
        dialog = ui.prompt("Rename", self.new_name, Typed, "rename", "cancel") \
            if self.new_name is not None else None
        return ui.dialog_layer(main_view(), dialog)
```

**Funcional:**

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class State:
    name: str = "notes.py"
    draft: str = "notes.py"
    renaming: bool = True

def view(state, set_state):
    if not state.renaming:
        return ui.label(state.name)
    return ui.dialog_layer(main_view(), ui.prompt(
        "Rename", state.draft, lambda text: set_state(draft=text),
        lambda: set_state(name=state.draft, renaming=False), lambda: set_state(renaming=False)))
```

## Propiedades y API

### `ui.prompt`

```python
prompt(
    title,
    value,
    on_input,
    on_submit,
    on_cancel,
    *,
    message=None,
    placeholder='',
    submit_label=None,
    cancel_label=None,
    id=None,
    width=440,
    theme=None,
)
```

Pide una línea de texto.

| Propiedad | Por defecto | Descripción |
| --- | --- | --- |
| `title` | *obligatorio* | Título. |
| `value` | *obligatorio* | Texto actual. |
| `message` | `None` | Texto sobre el campo. |
| `placeholder` | `""` | Texto de ayuda cuando está vacío. |
| `submit_label` | `None` | Texto del botón de aceptar. |
| `cancel_label` | `None` | Texto del botón de cancelar. |
| `id` | `None` | Id del campo (para `Command.focus`). |
| `width` | `440` | Ancho: píxeles, `"fill"`, `"shrink"` o `"fill:N"` (proporción). |
| `theme` | `None` | Tema a usar en lugar del actual (`pyzed.theme.current()`). |

Eventos: `on_input`, `on_submit`, `on_cancel` ([eventos](#eventos)).

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

## Relacionados

- [Confirmación](https://albakore.github.io/pyzed/es/library/confirm/): Una pregunta de sí o no, en rojo para acciones destructivas.
- [Campo de texto](https://albakore.github.io/pyzed/es/library/input/): Un campo de texto controlado con icono, placeholder y modo contraseña.
- [Capa de diálogo](https://albakore.github.io/pyzed/es/library/dialog-layer/): Centra un diálogo encima de tu vista con el fondo oscurecido.
