Canvas#

A drawing area for 2D vector graphics.

../../../_images/canvas-cocoa.png

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: Widget

Create a new Canvas widget.

Inherits from toga.Widget.

Parameters:
ClosedPath(x=None, y=None)#

Construct and yield a new ClosedPathContext context in the root context of this canvas.

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.

Yields:

The new ClosedPathContext context object.

Context()#

Construct and yield a new sub-Context within the root context of this Canvas.

Yields:

The new Context object.

Fill(x=None, y=None, color=BLACK, fill_rule=FillRule.NONZERO)#

Construct and yield a new FillContext in 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_to operation 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.

  • fill_rule (FillRule) – nonzero is the non-zero winding rule; evenodd is the even-odd winding rule.

  • color (Color | str | None) – The fill color.

Yields:

The new FillContext context object.

Stroke(x=None, y=None, color=BLACK, line_width=2.0, line_dash=None)#

Construct and yield a new StrokeContext in the root context of this canvas.

If both an x and y coordinate is provided, the drawing context will begin with a move_to operation 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 StrokeContext context object.

as_image(format=toga.Image)#

Render the canvas as an image.

Parameters:

format (type[ImageT]) – Format to provide. Defaults to Image; also supports PIL.Image.Image if Pillow is installed

Returns:

The canvas as an image of the specified type.

Return type:

ImageT

property context: Context#

The root context for the canvas.

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:
  • text (str) – The text to measure. Newlines will cause line breaks, but long lines will not be wrapped.

  • font (Font | None) – The font in which to draw the text. The default is the system font.

  • tightDEPRECATED: this argument has no effect.

Returns:

A tuple of (width, height).

Return type:

tuple[float, float]

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 redraw manually.

class toga.widgets.canvas.Context(canvas, **kwargs)#

Bases: DrawingObject

A drawing context for a canvas.

You should not create a Context directly; instead, you should use the Context() method on an existing context, or use Canvas.context to access the root context of the canvas.

Parameters:

canvas (toga.Canvas) –

ClosedPath(x=None, y=None)#

Construct and yield a new ClosedPath sub-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() and close_path().

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.

Yields:

The ClosedPathContext context object.

Context()#

Construct and yield a new sub-Context within this context.

Yields:

The new Context object.

Fill(x=None, y=None, color=BLACK, fill_rule=FillRule.NONZERO)#

Construct and yield a new Fill sub-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_path and fill.

If both an x and y coordinate is provided, the drawing context will begin with a move_to operation 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.

  • fill_rule (FillRule) – nonzero is the non-zero winding rule; evenodd is the even-odd winding rule.

  • color (str) – The fill color.

Yields:

The new FillContext context object.

Stroke(x=None, y=None, color=BLACK, line_width=2.0, line_dash=None)#

Construct and yield a new Stroke sub-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_path and stroke.

If both an x and y coordinate is provided, the drawing context will begin with a move_to operation 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 StrokeContext context object.

__getitem__(index)#

Returns the drawing object at the given index.

Parameters:

index (int) –

Return type:

DrawingObject

__len__()#

Returns the number of drawing objects that are in this context.

Return type:

int

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 Arc DrawingObject for the operation.

begin_path()#

Start a new path in the canvas context.

Returns:

The BeginPath DrawingObject for 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 BezierCurveTo DrawingObject for the operation.

property canvas: Canvas#

The canvas that is associated with this drawing context.

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 the ClosedPath() context manager.

Returns:

The ClosePath DrawingObject for the operation.

closed_path(x, y)#

DEPRECATED - use ClosedPath()

Parameters:
context()#

DEPRECATED - use Context()

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 Ellipse DrawingObject for 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:
  • fill_rule (FillRule) – nonzero is the non-zero winding rule; evenodd is the even-odd winding rule.

  • color (str) – The fill color.

  • preserveDEPRECATED: this argument has no effect.

Returns:

The Fill DrawingObject for 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:
  • x (float) – The x coordinate for the end point of the line segment.

  • y (float) – The y coordinate for the end point of the line segment.

Returns:

The LineTo DrawingObject for the operation.

move_to(x, y)#

Moves the current point of the canvas context without drawing.

Parameters:
  • x (float) – The x coordinate of the new current point.

  • y (float) – The y coordinate of the new current point.

Returns:

The MoveTo DrawingObject for 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:
  • cpx (float) – The x axis of the coordinate for the control point of the quadratic curve.

  • cpy (float) – The y axis of the coordinate for the control point of the quadratic curve.

  • x (float) – The x axis of the coordinate for the end point.

  • y (float) – The y axis of the coordinate for the end point.

Returns:

The QuadraticCurveTo DrawingObject for the operation.

rect(x, y, width, height)#

Draw a rectangle in the canvas context.

Parameters:
  • x (float) – The horizontal coordinate of the left of the rectangle.

  • y (float) – The vertical coordinate of the top of the rectangle.

  • width (float) – The width of the rectangle.

  • height (float) – The height of the rectangle.

Returns:

The Rect DrawingObject for the operation.

redraw()#

Calls Canvas.redraw on 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 ResetTransform DrawingObject.

rotate(radians)#

Add a rotation to the canvas context.

Parameters:

radians (float) – The angle to rotate clockwise in radians.

Returns:

The Rotate DrawingObject for the transformation.

scale(sx, sy)#

Add a scaling transformation to the canvas context.

Parameters:
  • sx (float) – Scale factor for the X dimension. A negative value flips the image horizontally.

  • sy (float) – Scale factor for the Y dimension. A negative value flips the image vertically.

Returns:

The Scale DrawingObject for the transformation.

stroke(color=BLACK, line_width=2.0, line_dash=None)#

Draw the current path as a stroke.

Parameters:
  • 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, expressed as alternating lengths of dashes and spaces. The default is a solid line.

Returns:

The Stroke DrawingObject for the operation.

translate(tx, ty)#

Add a translation to the canvas context.

Parameters:
  • tx (float) – Translation for the X dimension.

  • ty (float) – Translation for the Y dimension.

Returns:

The Translate DrawingObject for 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 WriteText DrawingObject for the operation.

class toga.widgets.canvas.DrawingObject#

Bases: ABC

A 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 the DrawingObject, which can be modified as shown in the Usage section.

DrawingObjects can also be created manually, then added to a context using the append() or insert() methods. Their constructors take the same arguments as the corresponding Context method, and their classes have the same names, but capitalized:

class toga.widgets.canvas.ClosedPathContext(canvas, x=None, y=None)#

Bases: Context

A 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_to and close_path.

If both an x and y coordinate is provided, the drawing context will begin with a move_to operation in that context.

You should not create a ClosedPathContext context directly; instead, you should use the ClosedPath() method on an existing context.

Parameters:
class toga.widgets.canvas.FillContext(canvas, x=None, y=None, color=BLACK, fill_rule=FillRule.NONZERO)#

Bases: ClosedPathContext

A 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_path and fill.

If both an x and y coordinate is provided, the drawing context will begin with a move_to operation in that context.

You should not create a FillContext context directly; instead, you should use the Fill() method on an existing context.

Parameters:
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: ClosedPathContext

Construct 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_path and stroke.

If both an x and y coordinate is provided, the drawing context will begin with a move_to operation in that context.

You should not create a StrokeContext context directly; instead, you should use the Stroke() method on an existing context.

Parameters:
property color: Color#

The color of the stroke.

protocol toga.widgets.canvas.OnTouchHandler#

typing.Protocol.

Classes that implement this protocol must have the following methods / attributes:

__call__(widget, x, y, **kwargs)#

A handler that will be invoked when a Canvas is touched with a finger or mouse.

Parameters:
  • widget (Canvas) – The canvas that was touched.

  • x (int) – X coordinate, relative to the left edge of the canvas.

  • y (int) – Y coordinate, relative to the top edge of the canvas.

  • kwargs – Ensures compatibility with arguments added in future versions.

protocol toga.widgets.canvas.OnResizeHandler#

typing.Protocol.

Classes that implement this protocol must have the following methods / attributes:

__call__(widget, width, height, **kwargs)#

A handler that will be invoked when a Canvas is resized.

Parameters:
  • widget (Canvas) – The canvas that was resized.

  • width (int) – The new width.

  • height (int) – The new height.

  • kwargs – Ensures compatibility with arguments added in future versions.