Canvas
A 2D drawing surface. shapes is a list made with pyzed.draw (rectangles, circles, arcs, paths, text, images…). Mouse callbacks receive coordinates relative to the canvas; with an id the geometry is cached between frames. The charts of this library are drawn with it.
pz.canvas · Category: Content · Full reference →


pz.canvas([ draw.rect(10, 10, 120, 80, fill="#74ade8", radius=8), draw.circle(200, 50, 40, fill="#a1c181"), draw.arc(300, 50, 40, 0, 270, stroke="#e5c07b", width=8, cap="round"), draw.polygon([(360, 90), (400, 10), (440, 90)], fill="#d07277"), draw.line(10, 120, 440, 120, stroke="#5d636f", width=2, dash=[6, 4]), draw.text(225, 150, "pz.canvas + pyzed.draw", color="#a9afbc", size=16, align_x="center"),], width=450, height=170)When to use
Section titled “When to use”- For charts, games, diagrams, drawing apps and custom widgets.
import pyzed as pzfrom pyzed import draw
pz.canvas([ draw.rect(10, 10, 120, 80, fill="#74ade8", radius=8), draw.circle(200, 50, 40, fill="#a1c181"), draw.arc(300, 50, 40, 0, 270, stroke="#e5c07b", width=8, cap="round"), draw.polygon([(360, 90), (400, 10), (440, 90)], fill="#d07277"), draw.line(10, 120, 440, 120, stroke="#5d636f", width=2, dash=[6, 4]), draw.text(225, 150, "pz.canvas + pyzed.draw", color="#a9afbc", size=16, align_x="center"),], width=450, height=170)Variants
Section titled “Variants”Shapes
Section titled “Shapes”

draw.rectCode
pz.canvas([draw.rect(10, 10, 140, 70, fill="#74ade8", radius=10)], width=160, height=90)

draw.circleCode
pz.canvas([draw.circle(50, 45, 36, fill="#a1c181")], width=100, height=90)

draw.arcCode
pz.canvas([draw.arc(50, 45, 34, 0, 270, stroke="#e5c07b", width=8, cap="round")], width=100, height=90)

draw.polygonCode
pz.canvas([draw.polygon([(10, 80), (50, 10), (90, 80)], fill="#d07277")], width=100, height=90)

draw.line(dash=)Code
pz.canvas([draw.line(10, 45, 190, 45, stroke="#c678dd", width=3, dash=[8, 5])], width=200, height=90)

draw.textCode
pz.canvas([draw.text(100, 45, "pyzed.draw", color="#74ade8", size=20, align_x="center", align_y="center")], width=200, height=90)Events
Section titled “Events”Canvas has 5 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 |
(x, y) |
Callable that receives (x, y) on press. |
on_release |
(x, y) |
Callable that receives (x, y) on release. |
on_right_press |
(x, y) |
Callable that receives (x, y) on right click. |
on_move |
(x, y) |
Called with (x, y) when the mouse moves. |
on_scroll |
(dx, dy) |
Callable that receives (dx, dy) in lines when the wheel is used. |
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 Paint(pz.App): def __init__(self): self.dots, self.drawing = [], False
def press(self, x, y): # on_press / on_move get the position self.drawing = True self.dots.append((x, y))
def move(self, x, y): if self.drawing: self.dots.append((x, y))
def view(self): return pz.canvas([draw.circle(x, y, 3, fill="#74ade8") for x, y in self.dots], width=420, height=200, cursor="crosshair", on_press=self.press, on_move=self.move, on_release=lambda x, y: setattr(self, "drawing", False), on_right_press=lambda x, y: self.dots.clear())from dataclasses import dataclass
@dataclassclass Dot: x: float y: float
class Paint(pz.App): dots = []
def update(self, message): match message: case Dot(x, y): self.dots = self.dots + [(x, y)] case "clear": self.dots = []
def view(self): return pz.canvas([draw.circle(x, y, 3, fill="#74ade8") for x, y in self.dots], width=420, height=200, on_press=Dot, on_right_press=lambda x, y: "clear")from dataclasses import dataclass
@dataclass(frozen=True)class State: dots: tuple = () zoom: float = 1.0
def view(state, set_state): shapes = [draw.circle(x, y, 3 * state.zoom, fill="#74ade8") for x, y in state.dots] return pz.canvas(shapes, width=420, height=200, on_press=lambda x, y: set_state(dots=state.dots + ((x, y),)), on_scroll=lambda dx, dy: set_state(zoom=max(0.5, state.zoom + dy * 0.1)))Properties and API
Section titled “Properties and API”pz.canvas
Section titled “pz.canvas”canvas( shapes=None, *, width=None, height=None, id=None, on_press=None, on_release=None, on_right_press=None, on_move=None, on_scroll=None, cursor=None,)A 2D drawing surface. shapes is a list created with pyzed.draw. Mouse callbacks receive coordinates relative to the canvas. With an id, the geometry is cached between frames and only recomputed when the shapes change. See the drawing with canvas guide.
| Property | Default | Description |
|---|---|---|
shapes |
None |
List of pyzed.draw shapes (nested lists are accepted). |
width |
None |
Width: pixels, "fill", "shrink" or "fill:N" (proportion). |
height |
None |
Height: pixels, "fill", "shrink" or "fill:N" (proportion). |
id |
None |
Enables the geometry cache. |
cursor |
None |
Mouse cursor ("crosshair", "pointer"…). |
Events: on_press, on_release, on_right_press, on_move, on_scroll (events).