Kivy - Drawing



All the GUI widgets in Kivy library have a Canvas property. Canvas is a place used for drawing various objects such as rectangle, ellipse, etc. It must be noted that Kivy doesn't have a separate Canvas widget for drawing shapes. Canvases of all widgets share a common coordinate space.

In Kivy, drawing is done on a Canvas related to any widget, with vertex instructions and context instructions.

  • Vertex instructions − Instructions used to draw basic geometric shapes like lines, rectangles, ellipses, etc. are called vertex instructions.

  • Context instructions − These instructions don't draw anything but manipulate the whole coordinate space, so to add colors to it, rotate, translate and scale it.

Vertex Instructions

These instructions are added to the Canvas in the form of different vertex objects. The vertex classes are defined in kivy.graphics.vertex_instructions module. As mentioned above, the drawing instructions are added to the context of a Canvas.

with self.canvas:
   vertex(**args)

The vertex_instructions module includes the following classes −

  • Bezier

  • BorderImage

  • Ellipse

  • Line

  • Mesh

  • Point

  • Quad

  • Rectangle

  • RoundedRectangle

  • SmoothLine

  • Triangle

Bezier

A Bezier curve is weighted by some control points, that we include within the instruction. In Kivy, Bezier is a vertex canvas instruction that draws this curve from a set of points given to the Beizer constructor as a parameter.

from kivy.graphics import Beizer
with self.canvas:
   Beizer(**args)

Parameters

Following parameters are defined in the Beizer class −

  • points − List of points in the format (x1, y1, x2, y2…)

  • loop − bool, defaults to False, Set the bezier curve to join the last point to the first.

  • segments − int, defaults to 180. Define how many segments are needed for drawing the curve. More number of segments results in smoother drawing.

  • dash_length − Length of a segment (if dashed), defaults to 1.

  • dash_offset − Distance between the end of a segment and the start of the next one, defaults to 0. Changing this makes it dashed.

Example

self.w=Widget()
with self.w.canvas:
   Color(0,1,1,1)
   Bezier(
      points=[700,400,450,300,300,350,350, 200,200,100,150,10],
      segments=20
   )
   Color(1,1,0,1)
   Point(
      points =[700,400,450,300,300,350,350, 200,200,100,150,10],
      pointsize= 3
   )

Output

It will produce the following output window −

kivy drawing bezier

The points are shown here for reference.

Ellipse

In Kivy framework, Ellipse is a vertex instruction. Depending on the segments required, it can display a polygon, a rectangle or an arc. If the width and height parameters are equal, the result is a circle.

from kivy.graphics import Ellipse
with self.canvas:
   Ellipse(**args)

Parameters

Following parameters are defined in the Ellipse class −

  • pos − the two element tuple giving the X and Y coordinate values of the center of the ellipse.

  • size − the two element tuple defining the width and height of ellipse in pixels.

  • angle_start − float, defaults to 0.0 specifies the starting angle, in degrees.

  • angle_end − float, defaults to 360.0 specifies the ending angle, in degrees.

  • segments − The number of segments of the ellipse. The ellipse drawing will be smoother if you have many segments. Use this property to create polygons with 3 or more sides. Values smaller than 3 will not be represented.

Example

self.w=Widget()
with self.w.canvas:
   Color(0.5, .2, 0.4, 1)
   d = 250
   Ellipse(pos=(360,200), size=(d+75, d))

Output

It will produce the following output window −

Kivy Drawing Ellipse

Rectangle

This vertex instruction draws a rectangle on the canvas, based on the position and dimensions given as parameters.

from kivy.graphics import Rectangle
with self.canvas:
   Rectangle(**args)

Parameters

Following parameters are defined in the Rectangle class −

  • pos − list of integers, specifying Position of the rectangle, in the format (x, y).

  • size − list of integers, Size of the rectangle, in the format (width, height).

Drawing a rectangle filled with a certain color is the recommended way of providing background to a label.

Example

def build(self):
   widget = Widget()
   with widget.canvas:
   Color(0, 0, 1, 1)
      Rectangle(
      pos=(50, 300), size_hint=(None, None),
      size=(300, 200)
   )
   lbl = Label(
      text='Hello World', font_size=24,
      pos=(Window.width / 2, 300), size=(200, 200),
      color=(0, 0, 1, 1)
   )
   with lbl.canvas.before:
      Color(1, 1, 0)
      Rectangle(pos=lbl.pos, size=lbl.size)
   
   widget.add_widget(lbl)
   
   return widget

Output

It will produce the following output window −

Kivy Drawing Rectangle

It may be noted that a Quad is a quadrilateral, a polygon with four vertices and need not be a rectangle. Similarly, a round rectangle is a rectangle with rounded vertices.

Line

In Kivy graphics, Line is a basic vertex instruction. The points property of Line object constructor has x and y coordinates of successive points. Kivy draws a line connecting the points successively.

from kivy.graphics import Line
with self.canvas:
   Line(**args)

Parameters

Following parameters are defined in the Line class −

  • points − list of points in the format (x1, y1, x2, y2…)

  • dash_length − int Length of a segment (if dashed), defaults to 1.

  • dash_offset − Offset between the end of a segment and the beginning of the next one, defaults to 0. Changing this makes it dashed.

  • dashes − list of ints in the format [ON length, offset, ON length, offset, …]. E.g. [2,4,1,6,8,2] would create a line with the first dash length 2 then an offset of 4 then a dash length of 1 then an offset of 6 and so on.

  • width − float - defines the Width of the line, defaults to 1.0.

Example

def build(self):
   box = BoxLayout(orientation='vertical')
   self.w = Widget()
   with self.w.canvas:
      Color(1, 0, 0, 1)
      Line(
         points=[700, 400, 450, 300, 300, 350, 350, 200, 200,  100, 150, 10],
         width=4
      )
      box.add_widget(self.w)
      
   return box

Output

It will produce the following output window −

Kivy Drawing Line

The Line class also has the properties bezier, ellipse, circle, rectangle with which the line points are used to draw respective shapes.

Triangle

With this vertex instruction, Kivy uses the points list to draw a triangle.

from kivy.graphics import Triangle
with self.canvas:
   Triangle(**args)

The points property is a list of x an y coordinates of three vertices of the triangle in the format (x1, y1, x2, y2, x3, y3).

Example

self.w=Widget()
with self.w.canvas:
   Color(1,1,1,1)
   self.triangle = Triangle(points=[100,100, 300,300, 500,100])

Output

It will produce the following output window −

Kivy Drawing Triangle

Updating a Drawing

It must be noted that the list attributes of all the graphics instruction classes (e.g. Triangle.points, Mesh.indices etc.) are not Kivy properties but Python properties. so, modifying this list won't update the drawing. It will be updated only when the list object itself is changed and not when list values are modified.

Let us change the vertex of the above rectangle by changing the point (300,300) to (400,300). We add a button to the above layout and bind it with a update method.

Example

Here is the complete code −

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import *
from kivy.properties import ObjectProperty
from kivy.core.window import Window

Window.size = (720, 400)

class mytriangleapp(App):
   triangle = ObjectProperty(None)
   title = "Drawing app"

   def updating(self, *args):
      self.triangle.points[3] = 400
      self.triangle.points = self.triangle.points

   def build(self):
      box = BoxLayout(orientation='vertical')
      self.w = Widget()
      with self.w.canvas:
         Color(1, 1, 1, 1)
         self.triangle = Triangle(points=[100, 100, 300, 300, 500, 100])
      self.b1 = Button(
         text='update', on_press=self.updating,
         size_hint=(None, .1)
      )
      box.add_widget(self.w)
      box.add_widget(self.b1)
      return box
mytriangleapp().run()

Output

When the above program is executed, we see a triangle and a button. When the button is clicked, the "triangle.points" list is updated also updating the triangle drawing.

Kivy Drawing Updating
Advertisements