Skip to content

Tree

A project panel: collapsible folders, an icon per file type and git status colors. TreeNode.from_paths(paths, status=...) builds the nodes, puts folders first and propagates the git status to the folders that contain changes. Each node’s id is its path; you own the expanded set and the selected id.

ui.tree · Category: Lists and menus · Full reference →

TreeTree
  • For files and any hierarchy: outlines, categories, settings sections.
  • status is "modified", "created", "deleted", "conflict" or "ignored".
import pyzed as pz
from pyzed import ui
class Explorer(pz.App):
def __init__(self):
self.nodes = ui.TreeNode.from_paths(["src/main.rs", "src/app.rs", "Cargo.toml"])
self.expanded = {"src"}
self.selected = None
def toggle(self, folder):
self.expanded ^= {folder}
def view(self):
return ui.tree(self.nodes, expanded=self.expanded, selected=self.selected,
on_toggle=self.toggle, on_select=lambda path: setattr(self, "selected", path))
Tree: CollapsedTree: Collapsed
Collapsed
Code
nodes = ui.TreeNode.from_paths(["src/main.rs", "src/app.rs", "src/ui/mod.rs", "src/ui/button.rs", "Cargo.toml"])
pz.container(ui.tree(nodes, expanded=set()), width=240)
Tree: expanded={"src"}Tree: expanded={"src"}
expanded={"src"}
Code
nodes = ui.TreeNode.from_paths(["src/main.rs", "src/app.rs", "src/ui/mod.rs", "src/ui/button.rs", "Cargo.toml"])
pz.container(ui.tree(nodes, expanded={"src"}), width=240)
Tree: expanded={"src", "src/ui"}Tree: expanded={"src", "src/ui"}
expanded={"src", "src/ui"}
Code
nodes = ui.TreeNode.from_paths(["src/main.rs", "src/app.rs", "src/ui/mod.rs", "src/ui/button.rs", "Cargo.toml"])
pz.container(ui.tree(nodes, expanded={"src", "src/ui"}, selected="src/ui/button.rs"), width=240)
Tree: status=Tree: status=
status=
Code
nodes = ui.TreeNode.from_paths(["src/app.rs", "src/new.rs", "src/old.rs", "build.log"],
status={"src/app.rs": "modified", "src/new.rs": "created", "src/old.rs": "deleted", "build.log": "ignored"})
pz.container(ui.tree(nodes, expanded={"src"}), width=240)
Tree: "conflict"Tree: "conflict"
"conflict"
Code
nodes = ui.TreeNode.from_paths(["merge.py", "ok.py"], status={"merge.py": "conflict"})
pz.container(ui.tree(nodes, expanded=set()), width=240)
Tree: item_height=20, indent=10Tree: item_height=20, indent=10
item_height=20, indent=10
Code
nodes = ui.TreeNode.from_paths(["src/main.rs", "src/app.rs", "src/ui/mod.rs", "src/ui/button.rs", "Cargo.toml"])
pz.container(ui.tree(nodes, expanded={"src", "src/ui"}, item_height=20, indent=10), width=240)
Tree: item_height=30, indent=20Tree: item_height=30, indent=20
item_height=30, indent=20
Code
nodes = ui.TreeNode.from_paths(["src/main.rs", "src/app.rs", "src/ui/mod.rs", "src/ui/button.rs", "Cargo.toml"])
pz.container(ui.tree(nodes, expanded={"src"}, item_height=30, indent=20), width=240)

on_open(id) runs on a double click of a file and on_context(id) on a right click.

Tree: Multiple selection and focusTree: Multiple selection and focus
Multiple selection and focus
Code
pz.container(ui.tree(ui.TreeNode.from_paths(["src/app.py", "src/ui.py", "README.md"]), expanded={"src"},
selected={"src/app.py", "README.md"}, focused="src/ui.py", on_open=on_open,
on_context=on_context), width=300)

Build the paths with pathlib and pass them to from_paths.

from pathlib import Path
root = Path(".")
paths = [p.relative_to(root).as_posix() for p in root.rglob("*")
if p.is_file() and ".git" not in p.parts]
nodes = ui.TreeNode.from_paths(paths)

Folders are nodes with children.

Tree: Nodes by handTree: Nodes by hand

Tree has 4 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_toggle (id) Called with the id of the clicked folder.
on_select (id) Called with the id of the clicked file.
on_open (id) Called with the id of a file that is double-clicked.
on_context (id) Called with the id of a row that is right-clicked (show a ui.menu there).

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().

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 Explorer(pz.App):
def __init__(self):
self.nodes = ui.TreeNode.from_paths(["src/main.rs", "src/app.rs", "Cargo.toml"])
self.expanded = {"src"}
self.selected = None
def toggle(self, folder): # on_toggle: the folder's id (its path)
self.expanded ^= {folder}
def view(self):
return ui.tree(self.nodes, expanded=self.expanded, selected=self.selected,
on_toggle=self.toggle,
on_select=lambda path: setattr(self, "selected", path), # click on a file
on_open=lambda path: print("open", path), # double click
on_context=lambda path: print("menu for", path)) # right click
tree(
nodes,
*,
expanded,
selected=None,
on_toggle=None,
on_select=None,
on_open=None,
on_context=None,
focused=None,
indent=14,
item_height=24,
theme=None,
)

A collapsible file tree, like a code editor’s project panel.

Property Default Description
nodes required List of TreeNode.
expanded required Set of open folder ids.
selected None One id or a collection of ids (multiple selection).
focused None Outlines the row the keyboard is on.
indent 14 Left indentation, in pixels.
item_height 24 Height of each row.
theme None Theme to use instead of the current one (pyzed.theme.current()).

Events: on_toggle, on_select, on_open, on_context (events).

Full reference →

@dataclass
class TreeNode(name, children=None, id=None, status=None, icon=None, icon_color=None)

A file or folder for ui.tree. Folders have children (a list). status is "modified", "created", "deleted", "conflict" or "ignored". TreeNode.from_paths(paths, status=None) builds the tree from paths like "src/main.rs", with folders first and the git status propagated to folders.

Property Default Description
name required Display name.
children None Children (None for a file).
id None Stable identifier used to focus or scroll it with a Command.
status None Git status.
icon None Name of a Lucide icon (pyzed icons lists them).
icon_color None Icon color: a theme token or a hex color.

Full reference →