Kivy GUI Tutorial

  1. Kivy Installation

    Download and install the latest version of python from Python Website if not already done.

    Set up virtual environment.

    Install Kivy using command python -m pip install kivy[base].

    Kivy installation may some times throw an error message like Could not find a version that satisfies the requirement kivy_deps.sdl2_dev~=0.3.1 (from versions: 0.4.2, 0.4.3)
    Refer next section to fix this error.

  2. Kivy Installation Error - Could not find a version that satisfies the requirement kivy_deps.sdl2_dev~=0.3.1 (from versions: 0.4.2, 0.4.3)

    This issue is caused by the fact that the latest version of kivy is not optimized for the python version that is installed in our machines.
    For example, at the time of writing this article, we had python 3.10.0 as the latest version in our machine and kivy version was 2.0.0 and this kivy version was throwing this error.
    Fix is to download and use the 3.9.x (we can use the latest 3.9 version) of the python.
    Follow the below steps for setting up and using kivy using Python 3.9.x.

    Navigate to the required folder in command prompt and set up virtual environment using below command and then activate the virtual environment.

    For Windows:
    py -3.9 -m venv <EnvName>
    For Linux, macOS:
    python3.9 -m venv <EnvName>

    Then use below command for installation:

    pip3.9 install kivy[base]
  3. To check if kivy installed successfully

    Open interpretor by typing py (windows) or python (Mac/Linux)
    Run below commands. If installation successful, we will get below output.

        import kivy
        print(kivy.__version__)
    
    Output:
    2.0.0
  4. Basic Kivy Application

    Code provided in the below sample is the bare minimum for creating a kivy application.

    First 2 lines import kivy and mention the current version.

    A kivy application should have a class that inherits the App module and a build function within it. This class acts as a start-up. As seen in the last 2 lines, when the main function executes, this in turns calls the class that inherits the App module and executes the build function. In other words build function acts as a Page Load function. All the steps that should happen when the GUI opens, should be mentioned in the build function. Here we can create the window title, size, color, define the layout, add the required controls, etc.

    Sample code given below. To run the code, copy this to a .py file and type py filename.py or python filename.py or py -3.9 filename.py or python3.9 filename.py as per the os and python version used.

    Copied
    import kivy
    kivy.require('2.0.0')
    
    from kivy.app import App
    from kivy.uix.label import Label
    
    class FirstKivyApp(App):
    
        def build(self):
            return Label(text='This is my first Kivy App')
    
    if __name__ == '__main__':
        FirstKivyApp().run()
    
    Basic kivy application
  5. Window size, color and title

    We can set up the size, background color of the window as below after importing Window module. Color values can be between 0 and 1 to obtain different colors. Code sample below:

        from kivy.core.window import Window
    
        self.title = 'My First Kivy App'
        Window.clearcolor = (1, 1, 1, 1)#White
        Window.size = (500, 500)
    
  6. Kivy Widgets

    Widgets can be considered as different types of controls provided by Kivy to get the desired look and feel inside a GUI window. Widgets are classified as follows:

    UX Widgets
    Button, Text, Label, Radio, Image, Video, Slider, Progressbar
    Layouts
    Anchor, Box, Float, Grid, Page, Stack
    Complex UX widgets
    Dropdown, Popup, Spinner

    We will go through some of the common widgets used.

  7. Button Widget

    To use a button, import Button module of kivy.uix and then create object as below

        from kivy.uix.button import Button
        btn = Button(text='New Button')
    

    An action can be bind to a button and different styles can be applied. Important properties are background_color, color, border, etc. Events are on_press, on_release, on_state(can be used to notify each time the state of button changes)
    Sample code and output given below:

    Copied
    import kivy
    kivy.require('2.0.0')
    
    from kivy.app import App
    from kivy.uix.button import Button
    from kivy.uix.label import Label
    from kivy.uix.gridlayout import GridLayout
    
    class RDCalculator(App):
    
        def build(self):
            self.lblR = Label(text="")
            btn = Button(text ="Calculate")
            btn.bind(on_press = self.calculate)              
    
            layout = GridLayout(cols=1)
            layout.add_widget(self.lblR)
            layout.add_widget(btn)
            return layout
            
        def calculate(self, instance):
            self.lblR.text = str("Calculation Done!!!")
            return
    
    if __name__ == '__main__':
        RDCalculator().run()
    
    Kivy button widget
  8. Label Widget

    Used to hold a text. Created as:

        from kivy.uix.label import Label
        lblR = Label(text="This is a Label")
    
  9. TextInput Widget

    Used as a textbox that can accept values from user. Created as:

        from kivy.uix.textinput import TextInput
        txtI = TextInput(text='', font_size=12,multiline=False)
    

    Use multiline property to create multiline textbox.

  10. Checkbox and Radio Widget

    Two state controls. Checkboxes when grouped becomes radio. Created as:

        from kivy.uix.checkbox import CheckBox
    

    Use active event to handle clicks.
    Sample code and output given below:

    Copied
    import kivy
    kivy.require('2.0.0')
    
    from kivy.app import App
    from kivy.uix.button import Button
    from kivy.uix.label import Label
    from kivy.uix.checkbox import CheckBox
    from kivy.uix.gridlayout import GridLayout
    
    class CBApp(App):
    
        def build(self):
            cb1 = CheckBox()
            cb2 = CheckBox()
            cb1.bind(active=clickMe)
    
            layout = GridLayout(cols=2)
            layout.add_widget(cb1)
            layout.add_widget(cb2)
            return layout
    
          
    def clickMe(checkbox, value):
        print('Value is ', value)
        return
    
    if __name__ == '__main__':
        CBApp().run()
    
    Kivy checkbox widget
  11. Image Widget

    To display an image. By default displayed at center. To change, use allow_stretch or keep_ratio properties. Created as:

        from kivy.uix.image import Image
        
        img = Image(source='imagename.png')
        asimg = AsyncImage(source="http://url.com/imagename.png")
    

    Third line creates an image that is loaded asynchronously so that application don't have to wait till image loads.

  12. Video Widget

    Used to display videos and streams.

        from kivy.uix. videoimport Video
        video = Video(source='testvideo.mpeg', state='play')
    

    Main properties are duration, eos (True means video is finished), loaded(True means ready for playback), state(play, pause, stop), volume .

  13. Kivy Layout Widgets

    Kivy uses different layout widgets to align UX controls within the window. We will go through the 3 main layouts that can be useful. Following 2 properties are important for mentioning the size and position of widgets within layout.

    size_hint
    Defines size of widgets as fraction of window size. Values ranges from 0 to 1
    pos_hint
    Position relative to parent
  14. Kivy BoxLayout

    Widgets arranged in a sequential manner, horizontal or vertical. Default is horizontal. Following code creates a box, which is of half the size and width of the window. 2 widgets are aligned horizontally within the box.

    Sample code and output given below:

    Copied
    import kivy
    kivy.require('2.0.0')
    
    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.label import Label
    from kivy.uix.button import Button
    
    class FirstKivyApp(App):
    
        def build(self):
            layout = BoxLayout(size_hint=(.5, .5))
            btn = Button(text='Button', size_hint=(1, .4))
            lbl = Button(text='Label', size_hint=(.5, 1))
            layout.add_widget(btn)
            layout.add_widget(lbl)
            return layout
    
    if __name__ == '__main__':
        FirstKivyApp().run()
    
    Kivy box layout

    Important properties of BoxLayout are minimum_height, minimum_width, orientation, padding (space between box and widgets within) and spacing (space between widgets) .

  15. Kivy GridLayout

    Allows you to arrange widgets as rows and columns. Below code defines a grid with 3 columns. When we add widgets, it will get added to the cells in mentioned order. When a fourth widget is added, second row is automatically created and widget placed there.

    Sample code and output given below:

    Copied
    import kivy
    kivy.require('2.0.0')
    
    from kivy.app import App
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.label import Label
    from kivy.uix.button import Button
    
    class FirstKivyApp(App):
    
        def build(self):
            layout = GridLayout(cols=3)
            btn1 = Button(text='Button 1')
            lbl1 = Button(text='Label 1')
            lbl2 = Label(text='Label 2')
            btn2 = Button(text='Button 2')
            layout.add_widget(btn1)
            layout.add_widget(lbl1)
            layout.add_widget(lbl2)
            layout.add_widget(btn2)
            return layout
    
    if __name__ == '__main__':
        FirstKivyApp().run()
    
    Kivy grid layout

    Main properties are col_default_width, col_force_default(If True, col_default_width is used instead of width and size_hint properties), cols, minimum_height, minimum_width, orientation(default from left to right, top to bottom (lr-tb). Allows 8 different combinations like tb-lr), padding, spacing .

  16. Kivy AnchorLayout

    Aligns widgets at top, bottom, left or right. See samples below.

        layout = AnchorLayout()
        btn = Button(text='Button at center')
        layout.add_widget(btn)
    
        layout = AnchorLayout(anchor_x='right')
        btn = Button(text='Button at center right')
        layout.add_widget(btn)
    
        layout = AnchorLayout(anchor_x='left', anchor_y='top')
        btn = Button(text='Button at top left')
        layout.add_widget(btn)
    

    Main properties are anchor_X, anchor_y, padding .

  17. Colspan in Kivy – Combine multiple layouts

    GridLayout doesn't have colspan feature. We can combine different layouts to get the desired structure. The below example combines grid and box layout to get 2 items in first row and one item in second row.

    The below example combines grid and box layout to get 2 items in first row and one item in second row.

    Copied
    import kivy
    kivy.require('2.0.0')
    
    from kivy.app import App
    from kivy.core.window import Window
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.textinput import TextInput
    from kivy.uix.button import Button
    
    class FirstKivyApp(App):
    
        def build(self):
            Window.clearcolor = (.3,.5, 1, 1)
            txt1 = TextInput(text='First Textbox')
            txt2 = TextInput(text='Second Textbox')
            blayout = BoxLayout(padding=20, spacing=10)
            blayout.add_widget(txt1)
            blayout.add_widget(txt2)
            glayout = GridLayout(cols=1, padding=50)
            glayout.add_widget(blayout)        
            btn = Button(text='Button', size_hint=(1, 1))
            glayout.add_widget(btn)
            return glayout
    
    if __name__ == '__main__':
        FirstKivyApp().run()
    
    Kivy combine multiple layouts
  18. Applying style to widgets

    We have 3 option to apply style to widgets. Using markups, comma separated values or KV language.
    See the example below which has 3 labels using different style options.

    Copied
    import kivy
    kivy.require('2.0.0')
    
    from kivy.app import App
    from kivy.uix.label import Label
    from kivy.uix.gridlayout import GridLayout
    from kivy.core.window import Window
    from kivy.lang import Builder
    
    lblKVLang = Builder.load_string("""
    Label:
        text: "KV Lang Style"
        font_size: '25'
        color: "#00f2f3"
    """)
    
    class TestApp(App):
    
        def build(self):
            
            lblM = Label(text='[b][color=#ff00ff]Markup Style[/color][/b]',
            markup = True)
            lblA = Label(text="Attribute Style", color =(0, 0, .5, 1),
            font_size ="15sp", size_hint=(1.0, 1.0))
            lblK = Label()
            layout = GridLayout(cols=1)
            layout.add_widget(lblM)
            layout.add_widget(lblA)
            layout.add_widget(lblKVLang)
            return layout
    
    if __name__ == '__main__':
        TestApp().run()
    
    Kivy - applying style to widgets
  19. KV Language

    We have placed KV Language tutorial in a separate page since it contains multiple sections. Won't take much time to understand the concepts. Have a look.

Absolute Code Works - Python Topics