Select your language

Widgets are not only good to represent buttons, labels or checkboxes. No, you can use them as a canvas for your atristic talent. You will learn how to draw on the canvas of a widget, the use of colors and the grapic element line. Plus, you'll see how to create a dropdown list.

Introduction

Every widget hast it. A canvas. The canvas is what the name tells. This object will be used if you want to draw with a widget. No matter what. If it  is a simple line, a rectangle, circle or a texture (image). Everything is drawn on the canvas.

The code

The nicessary modules that need to be imported include a coulple of new elements.

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.graphics import Color, Line
  • A FloatLayout gives you full control over the position of the widgets on that layout. You can define the size and position of every element easily.
  • The general class Widget is the base class for all other widgets, such as buttons. It is just missing all the customized functions and serves as the container for the canvas we need to draw on
  • A DropDown works like the well known drop down list you might be familiar with from Excel. But other than in a spread sheet can a drop down hold any widget as elemnts. You can add buttons, labesl etc to structure and select elements
  • The Color is used to define the color of our line. It holds a list of r, g, b values. Note that Kivy does not count form 0-255 but from 0-1 and you have to convert the values accordingly.
  • The Line is basically a dictionary that consist of a list of x-y coordinates and e.g. the width of the line.

The first class we define is MyPaintWidget and inhertis from Widget.

class MyPaintWidget(Widget):
    color=Color(1,1,0)

    def on_touch_down(self, touch):
        with self.canvas:
            Color(rgb = self.color.rgb)
            touch.ud['line'] = Line(points=(touch.x, touch.y), width = 4)

    def on_touch_move(self, touch):
        touch.ud['line'].points += [touch.x, touch.y]

After defining an initial color do we overload the on_touch_down function. When the user clicks on the screen do we set the color of the drawing operation we are going to perform first. Next we use an in-built dictionary of  the MotionEvent called touch.ud. The name line might be precise enough. The line in the on_touch_down function consists of only one pair of x-y coordinates. You can think of them as the starting point. We also define the widht of the line to be 4px.

Now, when the user starts dragging his mouse or finger over the screen and the on-touch_move event is called will we add x-y coordinate pairs to that line and it will miraculously be drawn on the canvas.

Adding a little color to the lines might be nice. That's why we add a dropdown list which lets you choose from two colors.

class ColorDropDown(DropDown):
    def __init__(self, **kwargs):
        super(ColorDropDown,self).__init__(**kwargs)

        blue = Button(text='Blue', size_hint_y = None, height = 35)
        self.add_widget(blue)
        blue.bind(on_release = lambda blue: self.select(Color(0,0,1)))

        green = Button(text='Green', size_hint_y = None, height = 35)
        self.add_widget(green)
        green.bind(on_release = lambda green : self.select(Color(0,1,0)))

Once the calss is instantiated two buttons (blue and green) are added to the dropdown list. You may make them taller or smaller by modifying the height property. The button is then bound to the on_release event ot the button is then bound to the select method of the dropdown. That means once a button is released the value which we pass to the select method is available as a result. And we pass the color we want the line to be.

Finally we build the app.

class MyPaintApp(App):
    def build(self):
        layout = FloatLayout(size=(600,600))
        button = Button(text = 'Choose color', pos_hint = {'left':1, 'top': 1}, size_hint = (0.2, 0.2))
        dropdown = ColorDropDown()
        button.bind(on_release = dropdown.open)
        widget = MyPaintWidget(size_hint = (1,1))
        dropdown.bind(on_select = lambda instance, x : setattr(widget, 'color', x))
        layout.add_widget(widget)
        layout.add_widget(button)

        return layout

if __name__ == '__main__':
    MyPaintApp().run()
  • The layout will be 600x600px big
  • The Button which opens the dropdown list is labelled *Choose color*
  • The button is bound to the open function of the dropdown
  • The MyPaintWidget is set to be as big as the layout by setting the size_hint = (1,1)
  • When the buttons of the dropdown are pressed an the select methond got called is the on_select method called. This will then set the color attribute of our MyPaintWidget

What's Next

Next we are going to use our knowledge to create a first game.