October 15, 2024

Kivy Project Creation: let’s simplify things

Spread the love

I don’t know about you but understanding how exactly the UI element connects with the functionality took me quite long. The good and bad thing about using Kivy to me was the flexibility of creating the UI elements in multiple ways. There are multiple ways to tackle the same situation which can cause a lot of confusion. In this article, I will try my best to go over that confusion and help you understand the quirks of creating a Kivy Project.

Method 1: Creating the UI elements and logic in one file

from kivy.app import App
from kivy.uix.button import Button

class TestApp(App):
    def build(self):
        button = Button(text='Button 1')
        button.bind(on_press=self.on_press_button)
        return button
    
    def on_press_button(self, instance):
        print('you pressed the button')


TestApp().run()

Let’s walk through the code:

  • We first define a class, TestApp, which inherits from App (imported from kivy.app)
  • In order to add UI elements we need to override the build method and whatever it returns is the main element.
  • In the above example, we return a button. So a button is displayed on the screen.
  • We then bind that button to a method which is later defined as on_press_button, which simply prints a text to the console.

Method 2: Seperating the UI element and the logic

This approach is beneficial when you are working with a lot of UI elements and you need to handle the logic for each of them. If we were to implement multiple UI elements using the 1st method, it will get complicated very fast. So instead, we will use Kv language to separate the UI elements and use python files for the logic.

Let’s implement the above code using this approach:

-- Python File (main.py)
from kivy.app import App

class TestApp(App):
    pass

TestApp().run()

-- Python File (button_press.py) -> handles the button press logic
from kivy.uix.button import Button

class ButtonPress(Button):
    def on_button_press(self):
        print('Button clicked')

-- Kv File (test.kv)
#:kivy 1.0
#: import button_press button_press

ButtonPress:

<ButtonPress>:
    text: 'Button 1'
    on_press: root.on_button_press()

Let’s walk through the code:

  • Python File (main.py):
    • This file is responsible only for running our main application
  • Python File (button_press.py):
    • This file is responsible for the button press logic.
    • Here we create a class ButtonPress which inherits Button class from kivy.uix.button
    • In this file we define a function which can be used by our UI element
  • Kv File (test.kv):
    • The file name is very important here, it should match the main class name without App. You could use lower cases for the name. For example, our main class is TestApp so we need to keep the file name as test.
    • We need to import the button_press file here because we need to import the function which should be associated with the UI element. To import a python file, the syntax is ->
      #: import file_name file_name
    • Once the file is imported, we need to define the primary UI by entering the name of the class followed by :
      ButtonPress:
    • Please note, the reson we need to define the main UI is becuase in our python file we are not overriding the build method. If we were then whatever the that build method returns, would be the UI element.
    • Then, we can define what is contained in that primary UI element by entering the name of the class surrounded by <>
      <ButtonPress>
    • Inside this we would define the various properties of the UI element
  • This might seem a lot of work but in the long run it gets easier to manage multiple UI elements and various logic associated with it.

Things to note

In the Kv file, we could define multiple UI elements but the one which is defined at the top (the one followed by : ) is the one that is shown on the screen

#:kivy 1.0
#: import button_press button_press

Test:

<ButtonPress>:
    text: 'Button 1'
    on_press: root.on_button_press()

<Test@Label>:
    text: 'Lable 1'

Here, we have defined two elements but since we have ” Test: ” at the top, that particular element will be shown on the screen.

You must be wondering what is that new syntax <Test@Label> and where is it coming from? That new syntax had me scratching my head for hours until I finally understood what that is. It’s a class name that inherits a class from Kivy. In our case, it’s the Test class that inherits Label from Kivy. In such a case, we don’t need a python file to define a class. We only need a python file when we need to define a function associated with the element.


I will update this article with any other nuances I find along the way. Also, feel free to reach out if you have any suggestions. Thanks.


Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *