Choice
A message with your own buttons: options are (label, on_press) pairs and the last one is the main one.
ui.choice · Category: Dialogs · Full reference →


ui.dialog_layer(main_view(), ui.choice( "notes.py already exists in this folder.", [("Keep both", on_keep), ("Skip", on_skip), ("Replace", on_replace)], on_cancel, title="File exists", width=420,))When to use
Section titled “When to use”- When a question has more than two answers (Keep both / Replace / Skip).
from pyzed import ui
ui.dialog_layer(main_view(), ui.choice( "notes.py already exists in this folder.", [("Keep both", on_keep), ("Skip", on_skip), ("Replace", on_replace)], on_cancel, title="File exists", width=420,))Variants
Section titled “Variants”Options
Section titled “Options”

Code
ui.choice("Open the project in…", [("This window", on_here), ("New window", on_new)], on_cancel, width=360)

Code
ui.choice("notes.py already exists.", [("Keep both", on_keep), ("Skip", on_skip), ("Replace", on_replace)], on_cancel, title="File exists", width=400)Events
Section titled “Events”Choice has 1 event of its own, listed below. Like every widget it also has the 18 common events (click, double_click, right_click, mouse_enter, drag, key_down, resize…), attached with .on(...): see Events and Events of every component.
| Event | Handler gets | When |
|---|---|---|
on_cancel |
() |
The close icon. |
Handler gets is what Pyzed passes to your callable: () means nothing. Any handler can also be a message (a value that is not callable), which goes to update().
Handling the events
Section titled “Handling the events”The same events written three ways. Imperative: methods of the app change self. Declarative: the handlers produce messages and one update() decides. Functional: a pure function draws an immutable state and asks for changes with set_state(...). See Imperative, declarative and functional.
class Copy(pz.App): def __init__(self): self.asking, self.answer = True, None
def answer_with(self, what): self.asking, self.answer = False, what
def view(self): dialog = ui.choice("notes.py already exists in this folder.", [("Keep both", lambda: self.answer_with("both")), # one handler per option ("Replace", lambda: self.answer_with("replace"))], lambda: setattr(self, "asking", False), # on_cancel: the ✕ title="File exists") return ui.dialog_layer(main_view(), dialog if self.asking else None)from dataclasses import dataclass
@dataclassclass Answer: what: str
class Copy(pz.App): asking = True
def update(self, message): match message: case Answer(what): self.asking = False print("chose", what) case "cancel": self.asking = False
def view(self): dialog = ui.choice("notes.py already exists.", [("Keep both", Answer("both")), ("Replace", Answer("replace"))], "cancel") return ui.dialog_layer(main_view(), dialog if self.asking else None)from dataclasses import dataclass
@dataclass(frozen=True)class State: answer: str = ""
def view(state, set_state): if state.answer: return ui.label(f"You chose: {state.answer}") return ui.dialog_layer(main_view(), ui.choice( "notes.py already exists.", [(label, lambda a=answer: set_state(answer=a)) for label, answer in (("Keep both", "both"), ("Replace", "replace"))], lambda: set_state(answer="cancel")))Properties and API
Section titled “Properties and API”ui.choice
Section titled “ui.choice”choice(message, options, on_cancel, *, title=None, width=440, theme=None)A message with your own buttons.
| Property | Default | Description |
|---|---|---|
message |
required | Any Python value, or a callable. |
options |
required | (label, on_press) pairs; the last one is the main button. |
title |
None |
Title. |
width |
440 |
Width: pixels, "fill", "shrink" or "fill:N" (proportion). |
theme |
None |
Theme to use instead of the current one (pyzed.theme.current()). |
Events: on_cancel (events).