Python’s Kivy — Self, Root, App?
Do you know when to use each of these?
Ah Kivy, a great open source Python framework for developing multi-platform GUIs.
I have been wanting to use this framework for a long time but often got stuck on how to access properties/data between the Python file (.py) and the Kivy file (.kv).
After reading Kivy documentation, Stack Overflow posts, and watching YouTube videos, I still found myself confused on when to use ‘self’, ‘root’ and ‘app’ and even worse… ‘app.root’!?
So I wanted to sort this out once and for all and create a Kivy App that describes its own behaviour for referencing self, root and app. You could call it a ‘Cheat Sheet’ that may also help you if you forget how to access a property or object in Kivy.
If you already have Kivy installed, please feel free to copy and paste the code below into your text editor of choice, save it as main.py and run it.
How does this work?
When considering this cheat sheet we have to remember that it’s an app full of buttons. Why do we have to remember this? Because that means that the button is ‘Self’ in this context!
In an app full of buttons, you can only count on your-self. If we want a button to do something to itself, we must refer to it as ‘Self’. This means that if we look at the code above, specifically the Button with the text: str(self), it will be returning its own object (as a string). Similarly, if you wanted to access a property within your own button/self, you can see the example in the code where the Button has the text: self.self_widget
Let’s do a root-cause analysis on Root. Often the root of all problems is understanding what is ‘Root’. A nice way to remember where the root is, is by referring to the code that’s not indented in your KV file. If it refers to a class in your python code it will have a weird <> surrounding it.
We have two root examples in the code above… The first is <OtherClass> which is found at the top of the KV code (also in the Python section as a class, hence the <>). The other is created in the build method within the Main class: self.root = “Main App Class Root”.
How do you access <OtherClass> in your KV file? Easy… root. What about the one in the Build Method/Main Class? app.root! What’s the deal with App? Let’s explain now…
What’s h-app-ening with this App business? Well this is the engine for the whole Kivy App and it therefore deserves its own reference point. App is used to reference the class where it inherits from kivy.app import App. It contains the build function which builds the app (surprise, surprise). Therefore, it is nice that we can refer to this class from a kivy file using…app.
To see this in action within the code refer to Button: text: str(app). It returns the Main class object from the KV section.
Additional Mentions — Parent and Children
The Kivy App works in a Tree-Like fashion. Here is an illustration of the Cheat Sheet App represented as a tree:
Within the code provided above, you probably noticed that parent and children was used. This is to access different parts of the tree from a particular origin. I’ll have to admit, making a label as a child widget for a button is weird. But as it turns out, it worked well to demonstrate how to access a self.children property!
And on that point…
This is a weird App and truth be told, it was created by a weird person! But hopefully this article and code has helped you understand how to access different parts of a Kivy App with self, root and app.
Please feel free to play around with this code to get a better understanding for yourself. Or better yet, please provide feedback on what I could do better… Should I have used StringProperty() in this code?