Split button
A button with a separate chevron on the right. on_press runs the main action and on_menu usually opens a ui.menu inside a ui.popover with the alternatives.
ui.split_button · Category: Actions · Full reference →


pz.row([ ui.split_button("Run", on_run, on_menu, icon="play"), ui.split_button("Deploy", on_deploy, on_menu, variant="solid"),], spacing=12)When to use
Section titled “When to use”- When one action is the usual one but there are a few variations (Run / Run with arguments).
- Avoid it when the options are equally important: use a Select.
import pyzed as pzfrom pyzed import ui
class Runner(pz.App): def __init__(self): self.menu_open = False
def view(self): button = ui.split_button("Run", self.run, lambda: setattr(self, "menu_open", True), icon="play") menu = ui.menu([ui.MenuItem("Run with arguments…", self.run_args), ui.MenuItem("Debug", self.debug, icon="bug")]) if self.menu_open else None return ui.popover(button, menu, y=32, on_dismiss=lambda: setattr(self, "menu_open", False))Variants
Section titled “Variants”Variant
Section titled “Variant”

variant="filled"Code
ui.split_button("Run", on_run, on_menu, icon="play")

variant="ghost"Code
ui.split_button("Run", on_run, on_menu, icon="play", variant="ghost")

variant="outline"Code
ui.split_button("Run", on_run, on_menu, icon="play", variant="outline")

variant="solid"Code
ui.split_button("Deploy", on_deploy, on_menu, icon="rocket", variant="solid")

size="sm"Code
ui.split_button("Build", on_build, on_menu, size="sm")

size="md"Code
ui.split_button("Build", on_build, on_menu, size="md")

size="lg"Code
ui.split_button("Build", on_build, on_menu, size="lg")Content
Section titled “Content”

Code
ui.split_button("Merge", on_merge, on_menu)

icon="git-merge"Code
ui.split_button("Merge", on_merge, on_menu, icon="git-merge")States and events
Section titled “States and events”

tint="success"Code
ui.split_button("Deploy", on_press, on_menu, tint="success")

disabled=TrueCode
ui.split_button("Run", on_press, on_menu, disabled=True)Events
Section titled “Events”Split button has 2 events 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_press |
() |
Message or callable sent on press. None disables the control. |
on_menu |
() |
Message or callable for the menu button. |
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 Runner(pz.App): def __init__(self): self.menu_open = False self.last = "nothing yet"
def run(self, how="run"): self.last, self.menu_open = how, False
def view(self): button = ui.split_button("Run", self.run, # on_press: the main action lambda: setattr(self, "menu_open", True), # on_menu: the arrow icon="play") menu = ui.menu([ui.MenuItem("Debug", lambda: self.run("debug"), icon="bug")]) return pz.column([ ui.popover(button, menu if self.menu_open else None, y=32, on_dismiss=lambda: setattr(self, "menu_open", False)), ui.label(f"Last: {self.last}"), ], spacing=8)from dataclasses import dataclass
@dataclassclass Run: how: str = "run"
class Runner(pz.App): menu_open = False last = "nothing yet"
def update(self, message): match message: case Run(how): self.last, self.menu_open = how, False case "menu": self.menu_open = True case "dismiss": self.menu_open = False
def view(self): menu = ui.menu([ui.MenuItem("Debug", Run("debug"), icon="bug")]) return ui.popover(ui.split_button("Run", Run(), "menu", icon="play"), menu if self.menu_open else None, y=32, on_dismiss="dismiss")from dataclasses import dataclass
@dataclass(frozen=True)class State: menu_open: bool = False last: str = "nothing yet"
def view(state, set_state): run = lambda how: set_state(last=how, menu_open=False) menu = ui.menu([ui.MenuItem("Debug", lambda: run("debug"), icon="bug")]) return ui.popover( ui.split_button("Run", lambda: run("run"), lambda: set_state(menu_open=True), icon="play"), menu if state.menu_open else None, y=32, on_dismiss=lambda: set_state(menu_open=False))Properties and API
Section titled “Properties and API”ui.split_button
Section titled “ui.split_button”split_button( content, on_press=None, on_menu=None, *, icon=None, variant='filled', tint=None, size='md', disabled=False, tooltip=None, theme=None,)A button with a separate arrow for more options. on_press runs the main action and on_menu usually opens a ui.menu in a ui.popover.
| Property | Default | Description |
|---|---|---|
content |
required | Button text. |
icon |
None |
Name of a Lucide icon (pyzed icons lists them). |
variant |
"filled" |
As in ui.button. |
tint |
None |
As in ui.button. |
size |
"md" |
"xs", "sm", "md" or "lg". |
disabled |
False |
Disables both halves. |
tooltip |
None |
Tooltip of the main half. |
theme |
None |
Theme to use instead of the current one (pyzed.theme.current()). |
Events: on_press, on_menu (events).