”;
Unlike some of the other GUI toolkits (such as TKinter for example), Kivy doesn”t have an independent Canvas widget. Instead, you need to use the canvas that each Widget in Kivy already has by default. When you create a widget, you can create all the instructions needed for drawing on its canvas.
We need to note that all the widgets have a different canvas but all the canvas draw in exactly the same drawing space, i.e. the coordinate space. Moreover, the drawing space is not limited to the position and size of the widget. The (0,0) of the drawing space is always the bottom-left corner.
The “canvas.before” property particularly useful when you need to manipulate the Color of an instance. On the other hand, canvas.after is used to execute any instructions after the children were added. It is called after traverse all the children.
Canvas in Kivy is a set of drawing instructions. To draw, you will need a Canvas object and Instruction objects. For example, to draw a rectangle on a label”s canvas −
from kivy.graphics import * with label.canvas: Color(1., 0, 0) # Add a red color # Add a rectangle Rectangle(pos=(10, 10), size=(500, 500))
If you have to do the same by not using Python”s context manager −
label.canvas.add(Color(1., 0, 0)) label.canvas.add(Rectangle(size=(500, 500)))
You can draw shapes such as rectangle, ellipse, line and Beizer on any widget”s canvas, including the Widget object itself. (Widget class is the base for all the other visual widgets in Kivy)
To draw a rectangle on the canvas, we need to specify the pos and size attributes −
from kivy.graphics import Rectangle Rectangle(**kwargs)
Parameters
-
pos − List of X and Y coordinate values specifying Position of the rectangle, in the format (x, y).
-
size − List specifying the width and height of the rectangle, in the format (width, height).
The following code draws a rectangle on the canvas of a Widget object −
widget=Widget() with widget.canvas: Color(0,0,1,1) Rectangle(pos=(50,300), size_hint=(None, None), size=(300,200))
The instructions Color and Rectangle are automatically added to the canvas object and will be used when the window is drawn.
Syntax
You may want to use the “kv” language syntax −
Widget: canvas: color: rgb: 0,0,1 Rectangle: pos: self.pos size: self.size
A Label object in Kivy doesn”t have a backgound color property. To get around this, you can draw a rectangle fille with the desired color on its canvas to lend background.
lbl = Label(text=''Hello World'', font_size=24) with lbl.canvas.before: Color(1,1,0) Rectangle(pos=lbl.pos, size=lbl.size)
Or, using the “kv” script −
Label: text:''Hello World'' font_size:24 canvas.before: Color: rgb: (1,1,0) Rectangle: pos:self.pos size=:self.size
Syntax
You can draw an ellipse on the canvas using the following syntax −
from kivy.graphics import Ellipse Ellipse(*args, **kwargs)
Parameters
-
segments − Defines how many segments are needed for drawing the ellipse. More the segments, drawing will be smoother if you have many segments.
-
angle_start − float, defaults to 0.0 and Specifies the starting angle, in degrees, of the disk portion.
-
angle_end − float, defaults to 360.0, specifies the ending angle, in degrees, of the disk portion.
-
angle_end − End angle of the ellipse in degrees, defaults to 360.
-
angle_start − Start angle of the ellipse in degrees, defaults to 0.
-
pos − the position on the canvas coordinate system
-
size − the X and Y radii of the ellipse. If both are equal, it becomes a circle.
You can also draw an image directly on the canvas, by assigning the image file as the source property of rectangle or ellipse.
Example 1
The following code implements all the drawing instructions explained above to display a rectangle, an ellipse and an image on a widget canvas. It also places a label with a rectangle having background color drawn on its canvas.
from kivy.app import App from kivy.uix.image import Image from kivy.uix.widget import Widget from kivy.uix.label import Label from kivy.uix.button import Button from kivy.graphics import * from kivy.core.window import Window Window.size = (720,400) class canvasdemoapp(App): def build(self): widget=Widget() # rectangle on canvas with widget.canvas: Color(0,0,1,1) Rectangle( pos=(50,300), size_hint=(None, None), size=(300,200) ) Color(0.5, .2, 0.4, 1) d = 100 # ellipse Ellipse(pos=(600,100), size=(d+75, d)) Color(.5,.5,.5) # image Rectangle(source=''kivy-logo.png'', pos=(50,100)) Color(1,1,1) Rectangle(source=''TPlogo.png'', pos=(300, 100)) # label with background 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) btn=Button( text=''Button'', font_size=24, background_color= (.8, .4, .3, 1), pos=(500,10) ) widget.add_widget(btn) return widget canvasdemoapp().run()
Output
When you run this code, it will produce the following output −
Example 2
The Widget object responds to all the touch events (such as on_touch_down and on_touch_move, etc.).
In the example below, a callback on the on_touch_down event on a Widget object obtains the coordinates where the touch event occurred and draws a circle (ellipse of equal X and Y radii) with random values of RGB colours.
from kivy.app import App from kivy.uix.widget import Widget from kivy.graphics import * import random from kivy.core.window import Window Window.size = (720,300) class widget(Widget): def on_touch_down(self, touch): colorR = random.randint(0, 255) colorG = random.randint(0, 255) colorB = random.randint(0, 255) self.canvas.add(Color( rgb=(colorR / 255.0, colorG / 255.0, colorB / 255.0) )) d = 30 self.canvas.add(Ellipse( pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d) )) class circlesapp(App): def build(self): return widget() circlesapp().run()
Output
Run the program and generate touch_down event at different places. Circles will be painted at locations.
”;