Menu
A floating context menu. Items are ui.MenuItem(label, on_press, icon=, keys=, checked=, danger=, disabled=); ui.SEPARATOR draws a line between groups and a plain string is a header. Show it with a Popover or a Layer.
ui.menu · Category: Lists and menus · Full reference →


ui.menu([ ui.MenuItem("New file", on_new, icon="file-plus", keys="ctrl-n"), ui.MenuItem("New folder", on_new_folder, icon="folder-plus"), ui.SEPARATOR, "EDIT", ui.MenuItem("Copy path", on_copy, keys="ctrl-alt-c"), ui.MenuItem("Soft wrap", on_wrap, checked=True), ui.SEPARATOR, ui.MenuItem("Delete", on_delete, icon="trash-2", danger=True),])When to use
Section titled “When to use”- For right-click menus and the options of a split button or an ellipsis button.
- Mark destructive actions with
danger=Trueand put them last.
from pyzed import ui
ui.menu([ ui.MenuItem("New file", on_new, icon="file-plus", keys="ctrl-n"), ui.MenuItem("New folder", on_new_folder, icon="folder-plus"), ui.SEPARATOR, "EDIT", ui.MenuItem("Copy path", on_copy, keys="ctrl-alt-c"), ui.MenuItem("Soft wrap", on_wrap, checked=True), ui.SEPARATOR, ui.MenuItem("Delete", on_delete, icon="trash-2", danger=True),])Variants
Section titled “Variants”

Code
ui.menu([ui.MenuItem("Open", on_open), ui.MenuItem("Rename", on_rename), ui.MenuItem("Duplicate", on_duplicate)], width=200)

icon=, keys=Code
ui.menu([ui.MenuItem("Copy", on_copy, icon="copy", keys="ctrl-c"), ui.MenuItem("Paste", on_paste, icon="clipboard", keys="ctrl-v")], width=220)

checked=Code
ui.menu([ui.MenuItem("Soft wrap", on_wrap, checked=True), ui.MenuItem("Minimap", on_minimap, checked=False)], width=200)

danger=TrueCode
ui.menu([ui.MenuItem("Rename", on_rename), ui.SEPARATOR, ui.MenuItem("Delete", on_delete, icon="trash-2", danger=True)], width=200)

disabled=TrueCode
ui.menu([ui.MenuItem("Undo", on_undo, keys="ctrl-z"), ui.MenuItem("Redo", on_redo, keys="ctrl-shift-z", disabled=True)], width=220)Groups
Section titled “Groups”

Code
ui.menu(["FILE", ui.MenuItem("New", on_new, keys="ctrl-n"), ui.SEPARATOR, "EDIT", ui.MenuItem("Find", on_find, keys="ctrl-f")], width=220)States and events
Section titled “States and events”

Code
ui.menu([ui.MenuItem("Share", on_press, icon="share", submenu=True), ui.MenuItem("Rename", on_press, description="F2 also works")])

max_height=140Code
ui.menu([ui.MenuItem(f"Recent {i}", on_press) for i in range(10)], max_height=140)Events
Section titled “Events”Menu 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_press |
() |
Message or callable sent on press. None disables the control. |
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 Files(pz.App): def __init__(self): self.wrap = True self.log = []
def view(self): return ui.menu([ ui.MenuItem("New file", lambda: self.log.append("new"), icon="file-plus", keys="ctrl-n"), ui.MenuItem("Soft wrap", lambda: setattr(self, "wrap", not self.wrap), checked=self.wrap), ui.SEPARATOR, ui.MenuItem("Delete", lambda: self.log.append("delete"), icon="trash-2", danger=True), ])class Files(pz.App): wrap = True
def update(self, message): # each item's on_press is a message match message: case "new": print("new file") case "wrap": self.wrap = not self.wrap
def view(self): return ui.menu([ui.MenuItem("New file", "new", icon="file-plus", keys="ctrl-n"), ui.MenuItem("Soft wrap", "wrap", checked=self.wrap)])from dataclasses import dataclass
@dataclass(frozen=True)class State: wrap: bool = True
def view(state, set_state): return ui.menu([ ui.MenuItem("Soft wrap", lambda: set_state(wrap=not state.wrap), checked=state.wrap), ui.MenuItem("Delete", None, icon="trash-2", danger=True, disabled=True), ])Properties and API
Section titled “Properties and API”ui.menu
Section titled “ui.menu”menu(items, *, width=240, max_height=None, theme=None)A floating context menu. Use ui.SEPARATOR between groups; a plain string is a header.
| Property | Default | Description |
|---|---|---|
items |
required | List of MenuItem, ui.SEPARATOR or strings. |
width |
240 |
Width: pixels, "fill", "shrink" or "fill:N" (proportion). |
max_height |
None |
Scrolls a menu taller than this. |
theme |
None |
Theme to use instead of the current one (pyzed.theme.current()). |
ui.MenuItem
Section titled “ui.MenuItem”@dataclassclass MenuItem(label, on_press=None, icon=None, keys=None, disabled=False, danger=False, checked=None, description=None, submenu=False)An entry of ui.menu.
| Property | Default | Description |
|---|---|---|
label |
required | Label text. |
icon |
None |
Name of a Lucide icon (pyzed icons lists them). |
keys |
None |
Shortcut shown at the end, written as a string: "ctrl-s", "cmd-k cmd-s". |
disabled |
False |
Disables it (ignores clicks). |
danger |
False |
In red (destructive actions). |
checked |
None |
Shows a check mark (True/False) or nothing (None). |
description |
None |
A muted second line. |
submenu |
False |
Ends the row with a chevron; open the next menu beside it in on_press. |
Events: on_press (events).
ui.SEPARATOR
Section titled “ui.SEPARATOR”Separator for ui.menu.