Canvas¶
A drawing area for 2D vector graphics.
Usage¶
Canvas is a 2D vector graphics drawing area, whose API broadly follows the HTML5 Canvas API. The Canvas provides a drawing Context; drawing instructions are then added to that context by calling methods on the context. All positions and sizes are measured in CSS pixels.
For example, the following code will draw an orange horizontal line:
import toga
canvas = toga.Canvas()
context = canvas.context
context.begin_path()
context.move_to(20, 20)
context.line_to(160, 20)
context.stroke(color="orange")
Toga adds an additional layer of convenience to the base HTML5 API by providing context managers for operations that have a natural open/close life cycle. For example, the previous example could be replaced with:
import toga
canvas = toga.Canvas()
with canvas.context.Stroke(20, 20, color="orange") as stroke:
stroke.line_to(160, 20)
Any argument provided to a drawing operation or context object becomes a property of
that object. Those properties can be modified after creation, after which you should
invoke Canvas.redraw to request a redraw of the canvas.
Drawing operations can also be added to or removed from a context using the list
operations append, insert, remove and clear. In this case,
Canvas.redraw will be called automatically.
For example, if you were drawing a bar chart where the height of the bars changed over time, you don’t need to completely reset the canvas and redraw all the objects; you can use the same objects, only modifying the height of existing bars, or adding and removing bars as required.
In this example, we create 2 filled drawing objects, then manipulate those objects, requesting a redraw after each set of changes.
import toga
canvas = toga.Canvas()
with canvas.context.Fill(color="red") as fill:
circle = fill.arc(x=50, y=50, radius=15)
rect = fill.rect(x=50, y=50, width=15, height=15)
# We can then change the properties of the drawing objects.
# Make the circle smaller, and move it closer to the origin.
circle.x = 25
circle.y = 25
circle.radius = 5
canvas.redraw()
# Change the fill color to blue
fill.color = "blue"
canvas.redraw()
# Remove the rectangle from the canvas
fill.remove(rect)
For detailed tutorials on the use of Canvas drawing instructions, see the MDN
documentation for the HTML5 Canvas API. Other than the change
in naming conventions for methods - the HTML5 API uses lowerCamelCase, whereas the
Toga API uses snake_case - both APIs are very similar.
Notes¶
The Canvas API allows the use of handlers to respond to mouse/pointer events. These event handlers differentiate between “primary” and “alternate” modes of activation. When a mouse is in use, alternate activation will usually be interpreted as a “right click”; however, platforms may not implement an alternate activation mode. To ensure cross-platform compatibility, applications should not use the alternate press handlers as the sole mechanism for accessing critical functionality.
Reference¶
- class toga.Canvas(id=None, style=None, on_resize=None, on_press=None, on_activate=None, on_release=None, on_drag=None, on_alt_press=None, on_alt_release=None, on_alt_drag=None)¶
Bases:
WidgetCreate a new Canvas widget.
Inherits from
toga.Widget.- Parameters:
id – The ID for the widget.
style – A style object. If no style is provided, a default style will be applied to the widget.
on_resize (OnResizeHandler) – Initial
on_resizehandler.on_press (OnTouchHandler) – Initial
on_presshandler.on_activate (OnTouchHandler) – Initial
on_activatehandler.on_release (OnTouchHandler) – Initial
on_releasehandler.on_drag (OnTouchHandler) – Initial
on_draghandler.on_alt_press (OnTouchHandler) – Initial
on_alt_presshandler.on_alt_release (OnTouchHandler) – Initial
on_alt_releasehandler.on_alt_drag (OnTouchHandler) – Initial
on_alt_draghandler.
- ClosedPath(x=None, y=None)¶
Construct and yield a new
ClosedPathContextcontext in the root context of this canvas.- Parameters:
- Yields:
The new
ClosedPathContextcontext object.
- Context()¶
Construct and yield a new sub-
Contextwithin the root context of this Canvas.- Yields:
The new
Contextobject.
- Fill(x=None, y=None, color=BLACK, fill_rule=FillRule.NONZERO)¶
Construct and yield a new
FillContextin the root context of this canvas.A drawing operator that fills the path constructed in the context according to the current fill rule.
If both an x and y coordinate is provided, the drawing context will begin with a
move_tooperation in that context.- Parameters:
- Yields:
The new
FillContextcontext object.
- Stroke(x=None, y=None, color=BLACK, line_width=2.0, line_dash=None)¶
Construct and yield a new
StrokeContextin the root context of this canvas.If both an x and y coordinate is provided, the drawing context will begin with a
move_tooperation in that context.- Parameters:
x (float | None) – The x coordinate of the path’s starting point.
y (float | None) – The y coordinate of the path’s starting point.
color (Color | str | None) – The color for the stroke.
line_width (float) – The width of the stroke.
line_dash (list[float] | None) – The dash pattern to follow when drawing the line. Default is a solid line.
- Yields:
The new
StrokeContextcontext object.
- as_image(format=toga.Image)¶
Render the canvas as an image.
- Parameters:
format (type[ImageT]) – Format to provide. Defaults to
Image; also supportsPIL.Image.Imageif Pillow is installed, as well as any image types defined by installed image format plugins- Returns:
The canvas as an image of the specified type.
- Return type:
ImageT
- property enabled: bool¶
Is the widget currently enabled? i.e., can the user interact with the widget? ScrollContainer widgets cannot be disabled; this property will always return True; any attempt to modify it will be ignored.
- focus()¶
No-op; ScrollContainer cannot accept input focus
- measure_text(text, font=None, tight=None)¶
Measure the size at which
write_text()would render some text.- Parameters:
- Returns:
A tuple of
(width, height).- Return type:
- property on_activate: OnTouchHandler¶
The handler invoked when the canvas is pressed in a way indicating the pressed object should be activated. When a mouse is in use, this will usually be a double click with the primary (usually the left) mouse button.
This event is not supported on Android or iOS.
- property on_alt_drag: OnTouchHandler¶
The handler to invoke when the location of an alternate press changes.
This event is not supported on Android or iOS.
- property on_alt_press: OnTouchHandler¶
The handler to invoke when the canvas is pressed in an alternate manner. This will usually correspond to a secondary (usually the right) mouse button press.
This event is not supported on Android or iOS.
- property on_alt_release: OnTouchHandler¶
The handler to invoke when an alternate press is released.
This event is not supported on Android or iOS.
- property on_drag: OnTouchHandler¶
The handler invoked when the location of a press changes.
- property on_press: OnTouchHandler¶
The handler invoked when the canvas is pressed. When a mouse is being used, this press will be with the primary (usually the left) mouse button.
- property on_release: OnTouchHandler¶
The handler invoked when a press on the canvas ends.
- property on_resize: OnResizeHandler¶
The handler to invoke when the canvas is resized.
- redraw()¶
Redraw the Canvas.
The Canvas will be automatically redrawn after adding or removing a drawing object, or when the Canvas resizes. However, when you modify the properties of a drawing object, you must call
redrawmanually.
- class toga.widgets.canvas.Context(canvas, **kwargs)¶
Bases:
DrawingObjectA drawing context for a canvas.
You should not create a
Contextdirectly; instead, you should use theContext()method on an existing context, or useCanvas.contextto access the root context of the canvas.- Parameters:
canvas (toga.Canvas)
- ClosedPath(x=None, y=None)¶
Construct and yield a new
ClosedPathsub-context that will draw a closed path, starting from an origin.This is a context manager; it creates a new path and moves to the start coordinate; when the context exits, the path is closed. For fine-grained control of a path, you can use
begin_path()andclose_path().- Parameters:
- Yields:
The
ClosedPathContextcontext object.
- Context()¶
Construct and yield a new sub-
Contextwithin this context.- Yields:
The new
Contextobject.
- Fill(x=None, y=None, color=BLACK, fill_rule=FillRule.NONZERO)¶
Construct and yield a new
Fillsub-context within this context.This is a context manager; it creates a new path, and moves to the start coordinate; when the context exits, the path is closed with a fill. For fine-grained control of a path, you can use
begin_path,move_to,close_pathandfill.If both an x and y coordinate is provided, the drawing context will begin with a
move_tooperation in that context.- Parameters:
- Yields:
The new
FillContextcontext object.
- Stroke(x=None, y=None, color=BLACK, line_width=2.0, line_dash=None)¶
Construct and yield a new
Strokesub-context within this context.This is a context manager; it creates a new path, and moves to the start coordinate; when the context exits, the path is closed with a stroke. For fine-grained control of a path, you can use
begin_path,move_to,close_pathandstroke.If both an x and y coordinate is provided, the drawing context will begin with a
move_tooperation in that context.- Parameters:
x (float | None) – The x coordinate of the path’s starting point.
y (float | None) – The y coordinate of the path’s starting point.
color (str) – The color for the stroke.
line_width (float) – The width of the stroke.
line_dash (list[float] | None) – The dash pattern to follow when drawing the line. Default is a solid line.
- Yields:
The new
StrokeContextcontext object.
- __getitem__(index)¶
Returns the drawing object at the given index.
- Parameters:
index (int)
- Return type:
- append(obj)¶
Append a drawing object to the context.
- Parameters:
obj (DrawingObject) – The drawing object to add to the context.
- arc(x, y, radius, startangle=0.0, endangle=2 * pi, anticlockwise=False)¶
Draw a circular arc in the canvas context.
A full circle will be drawn by default; an arc can be drawn by specifying a start and end angle.
- Parameters:
x (float) – The X coordinate of the circle’s center.
y (float) – The Y coordinate of the circle’s center.
startangle (float) – The start angle in radians, measured clockwise from the positive X axis.
endangle (float) – The end angle in radians, measured clockwise from the positive X axis.
anticlockwise (bool) – If true, the arc is swept anticlockwise. The default is clockwise.
radius (float)
- Returns:
The
ArcDrawingObjectfor the operation.
- begin_path()¶
Start a new path in the canvas context.
- Returns:
The
BeginPathDrawingObjectfor the operation.
- bezier_curve_to(cp1x, cp1y, cp2x, cp2y, x, y)¶
Draw a Bézier curve in the canvas context.
A Bézier curve requires three points. The first two are control points; the third is the end point for the curve. The starting point is the last point in the current path, which can be changed using move_to() before creating the Bézier curve.
- Parameters:
cp1y (float) – The y coordinate for the first control point of the Bézier curve.
cp1x (float) – The x coordinate for the first control point of the Bézier curve.
cp2x (float) – The x coordinate for the second control point of the Bézier curve.
cp2y (float) – The y coordinate for the second control point of the Bézier curve.
x (float) – The x coordinate for the end point.
y (float) – The y coordinate for the end point.
- Returns:
The
BezierCurveToDrawingObjectfor the operation.
- clear()¶
Remove all drawing objects from the context.
- close_path()¶
Close the current path in the canvas context.
This closes the current path as a simple drawing operation. It should be paired with a
begin_path()operation; or, to complete a complete closed path, use theClosedPath()context manager.- Returns:
The
ClosePathDrawingObjectfor the operation.
- closed_path(x, y)¶
DEPRECATED - use
ClosedPath()
- ellipse(x, y, radiusx, radiusy, rotation=0.0, startangle=0.0, endangle=2 * pi, anticlockwise=False)¶
Draw an elliptical arc in the canvas context.
A full ellipse will be drawn by default; an arc can be drawn by specifying a start and end angle.
- Parameters:
x (float) – The X coordinate of the ellipse’s center.
y (float) – The Y coordinate of the ellipse’s center.
radiusx (float) – The ellipse’s horizontal axis radius.
radiusy (float) – The ellipse’s vertical axis radius.
rotation (float) – The ellipse’s rotation in radians, measured clockwise around its center.
startangle (float) – The start angle in radians, measured clockwise from the positive X axis.
endangle (float) – The end angle in radians, measured clockwise from the positive X axis.
anticlockwise (bool) – If true, the arc is swept anticlockwise. The default is clockwise.
- Returns:
The
EllipseDrawingObjectfor the operation.
- fill(color=BLACK, fill_rule=FillRule.NONZERO, preserve=None)¶
Fill the current path.
The fill can use either the Non-Zero or Even-Odd winding rule for filling paths.
- Parameters:
- Returns:
The
FillDrawingObjectfor the operation.
- insert(index, obj)¶
Insert a drawing object into the context at a specific index.
- Parameters:
index (int) – The index at which the drawing object should be inserted.
obj (DrawingObject) – The drawing object to add to the context.
- line_to(x, y)¶
Draw a line segment ending at a point in the canvas context.
- Parameters:
- Returns:
The
LineToDrawingObjectfor the operation.
- move_to(x, y)¶
Moves the current point of the canvas context without drawing.
- Parameters:
- Returns:
The
MoveToDrawingObjectfor the operation.
- new_path()¶
DEPRECATED - Use
begin_path().
- quadratic_curve_to(cpx, cpy, x, y)¶
Draw a quadratic curve in the canvas context.
A quadratic curve requires two points. The first point is a control point; the second is the end point. The starting point of the curve is the last point in the current path, which can be changed using
moveTo()before creating the quadratic curve.- Parameters:
- Returns:
The
QuadraticCurveToDrawingObjectfor the operation.
- rect(x, y, width, height)¶
Draw a rectangle in the canvas context.
- Parameters:
- Returns:
The
RectDrawingObjectfor the operation.
- redraw()¶
Calls
Canvas.redrawon the parent Canvas.
- remove(obj)¶
Remove a drawing object from the context.
- Parameters:
obj (DrawingObject) – The drawing object to remove.
- reset_transform()¶
Reset all transformations in the canvas context.
- Returns:
A
ResetTransformDrawingObject.
- rotate(radians)¶
Add a rotation to the canvas context.
- Parameters:
radians (float) – The angle to rotate clockwise in radians.
- Returns:
The
RotateDrawingObjectfor the transformation.
- scale(sx, sy)¶
Add a scaling transformation to the canvas context.
- Parameters:
- Returns:
The
ScaleDrawingObjectfor the transformation.
- stroke(color=BLACK, line_width=2.0, line_dash=None)¶
Draw the current path as a stroke.
- Parameters:
- Returns:
The
StrokeDrawingObjectfor the operation.
- translate(tx, ty)¶
Add a translation to the canvas context.
- Parameters:
- Returns:
The
TranslateDrawingObjectfor the transformation.
- write_text(text, x=0.0, y=0.0, font=None, baseline=Baseline.ALPHABETIC)¶
Write text at a given position in the canvas context.
Drawing text is effectively a series of path operations, so the text will have the color and fill properties of the canvas context.
- Parameters:
text (str) – The text to draw. Newlines will cause line breaks, but long lines will not be wrapped.
x (float) – The X coordinate of the text’s left edge.
y (float) – The Y coordinate: its meaning depends on
baseline.font (Font | None) – The font in which to draw the text. The default is the system font.
baseline (Baseline) – Alignment of text relative to the Y coordinate.
- Returns:
The
WriteTextDrawingObjectfor the operation.
- class toga.widgets.canvas.DrawingObject¶
Bases:
ABCA drawing operation in a
Context.Every context drawing method creates a
DrawingObject, adds it to the context, and returns it. Each argument passed to the method becomes a property of theDrawingObject, which can be modified as shown in the Usage section.DrawingObjectscan also be created manually, then added to a context using theappend()orinsert()methods. Their constructors take the same arguments as the correspondingContextmethod, and their classes have the same names, but capitalized:
- class toga.widgets.canvas.ClosedPathContext(canvas, x=None, y=None)¶
Bases:
ContextA drawing context that will build a closed path, starting from an origin.
This is a context manager; it creates a new path and moves to the start coordinate; when the context exits, the path is closed. For fine-grained control of a path, you can use
begin_path,move_toandclose_path.If both an x and y coordinate is provided, the drawing context will begin with a
move_tooperation in that context.You should not create a
ClosedPathContextcontext directly; instead, you should use theClosedPath()method on an existing context.- Parameters:
canvas (toga.Canvas)
x (float | None)
y (float | None)
- class toga.widgets.canvas.FillContext(canvas, x=None, y=None, color=BLACK, fill_rule=FillRule.NONZERO)¶
Bases:
ClosedPathContextA drawing context that will apply a fill to any paths all objects in the context.
The fill can use either the Non-Zero or Even-Odd winding rule for filling paths.
This is a context manager; it creates a new path, and moves to the start coordinate; when the context exits, the path is closed with a fill. For fine-grained control of a path, you can use
begin_path,move_to,close_pathandfill.If both an x and y coordinate is provided, the drawing context will begin with a
move_tooperation in that context.You should not create a
FillContextcontext directly; instead, you should use theFill()method on an existing context.- Parameters:
canvas (toga.Canvas)
x (float | None)
y (float | None)
color (str)
fill_rule (FillRule)
- property color: Color¶
The fill color.
- class toga.widgets.canvas.StrokeContext(canvas, x=None, y=None, color=BLACK, line_width=2.0, line_dash=None)¶
Bases:
ClosedPathContextConstruct a drawing context that will draw a stroke on all paths defined within the context.
This is a context manager; it creates a new path, and moves to the start coordinate; when the context exits, the path is drawn with the stroke. For fine-grained control of a path, you can use
begin_path,move_to,close_pathandstroke.If both an x and y coordinate is provided, the drawing context will begin with a
move_tooperation in that context.You should not create a
StrokeContextcontext directly; instead, you should use theStroke()method on an existing context.- Parameters:
- property color: Color¶
The color of the stroke.
- protocol toga.widgets.canvas.OnTouchHandler¶
-
Classes that implement this protocol must have the following methods / attributes:
- protocol toga.widgets.canvas.OnResizeHandler¶
-
Classes that implement this protocol must have the following methods / attributes:




