Table of Contents
Summary
When working in big apps, it can be useful to expose your widgets, and variables. This allows you to easily change the data for any of the widgets through a .kv file. Also, it allows non-programmers to make signifigant changes to the application, without having to dive into code!
The Problem
In our Kivy game, we have a cat object.
cat.py
#!Python
class Cat(Widget):
mCatSpeed = NumericProperty(20)
mCatMass = NumericProperty(50)
def Update(self, dt):
# Do physics calculations based on Speed and Mass
As you can see here, our python "cat" object is a Kivy Widget that has a few custom member variables: mCatSpeed and mCatMass.
What happens when you want to have 2 different cats, of different speeds? The larger cats go slower, the lighter cats go faster.
You could write code to generate these objects catFactory.py
#!Python
class CatFactory():
def GenerateCats(inRootWidget):
cat1 = Cat()
cat1.mCatSpeed = 10
cat1.mCatMass = 100
inRootWidget.add_widget(cat1)
cat2 = cat()
# ...etc
But now every time you want to change the cats, you have to go into this code and change the varaibles, and copy a lot of code with different names.
What happens when you want cats in different areas? Things start to get messy.
Data Driven Solution
Kivy allows us to data drive our application, which is a super useful, super powerful solution.
Lets say our cat lives inside a room, lets make the 3 cats like this:
room.kv
#!text
<Room>:
Cat:
id: fatCat
pos: 100, 100
mCatSpeed: 10
mCatMass: 100
Cat:
id: smallCat
pos: 100, 50
mCatSpeed: 50
mCatMass: 25
Pretty handy, right? You can now just write your different cats with whatever data you want, assuming they are set up the way you need.
What's better is that non-programmers (Artists, Designers) can now create large portions of your applications much more rapidly than doing it through code!
The technical
For a variable to be settable, like this by kivy, it must be a kivy property.
#!python
class MyWidget(Widget):
# Can be set in .kv files, since its a Kivy Property
speed1 = NumericProperty(0)
# Cannot be set, its not a Kivy Property
speed2 = 0
The variable is a bit finicky with naming too. It must be lowercased first letter!
#!python
class MyWidget(Widget):
# Works, as the first character is lowercased
speed1 = NumericProperty(0)
sPEEd2 = NumericProperty(0)
# Does not work, as the first character is capitalized
Speed3 = NumericProperty(0)
Sample Code
This sample is very basic, and shows how you can get the above results.
testWidget.py
#!python
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.properties import StringProperty, NumericProperty, ObjectProperty
# This import is required for the TestWidet.kv file to know what a Cat is.
import cat
Builder.load_file("TestWidget.kv")
class TapApp(App):
def build(self):
return TestWidget()
class TestWidget(Widget):
pass
if __name__ in ('__main__', '__android__'):
TapApp().run()
TestWidget.kv
#!text
<TestWidget>:
Cat:
pos: 100, 100
catSpeed: 30
cat.py
#!python
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.properties import StringProperty, NumericProperty, ObjectProperty
from kivy.clock import Clock
Builder.load_file("Cat.kv")
class Cat(Widget):
catSpeed = NumericProperty(20)
def __init__(self, **kwargs):
super(Cat, self).__init__(**kwargs)
Clock.schedule_interval(self.Update, 1.0 / 60.0)
def Update(self, dt):
print(self.catSpeed)
Cat.kv
#!text
<Cat>: