In the previous part we were creating and using some properties. In this lecture we’ll have a look at how properties are actually defined and used.
But before we delve into the topic, here’s some info for you.
*****
Book Info
I just published my Kivy book, GUI Programming with Python and Kivy. It’s pretty long (over 800 pages) and comprehensive. And, which also counts, easy to read. The book contains lots of illustrations.
This book covers all the basics that you need to know to start programming GUI applications with Python and Kivy. Throughout the book we are building a GUI application from scratch, a fully functional game using all kinds of tools that Kivy has to offer. It’s our Slugrace project, but covered in a much more in-depth manner.
Each part of the book starts with a theoretical introduction of a topic or idea that we then implement in the project. I assume you have no prior knowledge of the Kivy library, but you should have at least some basic knowledge of the Python programming language, including the object-oriented programming paradigm as this is what we will be using a lot in this book.
The book covers all the basic elements of Kivy that you have to know, like widgets, layouts, Kivy ids and properties, graphics, screens, animation, sound. Finally we’ll deploy the app to Windows. It is pretty comprehensive and after you finish it, I’m sure you’ll be able to create your own awesome GUI apps of any kind, not just games.
I hope you will have at least as much fun reading the book as I had writing it.
As far as this Kivy series is concerned, the following parts will contain the most important elements covered in the book. However, some elements will be presented in a simplified way here on my blog or omitted completely.
____________
If you are interested, you can purchase the book in four versions. Here are the links:
1) ebook – pdf version on my website – in full color
Here you can see the description of the book, sample graphics from the book and the full table of contents.
2) ebook – Kindle version on Amazon – in full color
3) paperback version on Amazon – in black and white
4) paperback version on Amazon – in full color
*****
And Now Let’s Move On…
Here’s the code that we used in the previous lecture:
# File name: test.py
...
class TestLayout(BoxLayout):
label = ObjectProperty()
button1 = ObjectProperty()
button2 = ObjectProperty()
def set_text(self):
self.label.text = 'CHANGED'
self.button1.text += '+'
self.button2.font_size += 5
...
As you can see, we defined the Kivy properties like we define class attributes, so on the class level, but then we used them like instance attributes inside the set_text method. So, do they behave like class attributes or like instance attributes? Well, Kivy properties are an interesting combination of both. We define them as class attributes, but they are not shared by all the instances of the class, so they behave like instance properties. This is because Kivy internally transforms them to instance attributes. What makes them more useful than instance properties, though, is that whenever we define a Kivy property, Kivy internally also associates an event with this property, using a naming convention of adding the prefix on_ to the name of the property. So, if the property’s name is state, the corresponding method will be on_state, and so on. This event is fired whenever the value of a property changes, this is why we don’t need to take care of the changes ourselves.
Let’s define a Kivy property, for example the NumericProperty and see how to use it. We’ll need to modify our test.kv and test.py files a little. Here’s the former:
# File name: test.kv
<TestLayout>:
label: _label
button1: _button1
button2: _button2
Button:
id: _button1
on_press: root.set_text()
Label:
id: _label
Button:
id: _button2
And here’s the latter:
# File name: test.py
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
# Don't forget to import NumericProperty.
from kivy.properties import ObjectProperty, NumericProperty
class TestLayout(BoxLayout):
label = ObjectProperty()
button1 = ObjectProperty()
button2 = ObjectProperty()
# We need a number, so a NumericProperty is the way to go.
# Let's initialize it to 0 by passing 0 as the default value.
counter = NumericProperty(0)
def set_text(self):
# Here we use the property just like an instance attribute.
self.button1.text = str(self.counter)
self.label.text = str(self.counter * 10)
self.button2.text = str(self.counter * 100)
self.counter += 1
class TestApp(App):
def build(self):
return TestLayout()
if __name__ == '__main__':
TestApp().run()
As you can see, I defined the property as a NumericProperty on the class level, just like a class attribute, but then used it inside a method like an instance attribute.
If you now run the program and press the first button a couple times, you should see something like this:
We’re going to add some properties to our project in the following parts of the series, but before we do that, in the next part we’ll take care of the app window’s size so that we don’t have to manually resize it whenever we run the app.