Quick search

Properties

The Properties classes are used when you create a EventDispatcher.

Warning

Kivy’s Properties are not to be confused with Python’s properties (i.e. the @property decorator and the <property> type).

Kivy’s property classes support:

Value Checking / Validation
When you assign a new value to a property, the value is checked to pass constraints implemented in the class such as validation. For example, validation for OptionProperty will make sure that the value is in a predefined list of possibilities. Validation for NumericProperty will check that your value is a numeric type. This prevents many errors early on.
Observer Pattern
You can specify what should happen when a property’s value changes. You can bind your own function as a callback to changes of a Property. If, for example, you want a piece of code to be called when a widget’s pos property changes, you can bind a function to it.
Better Memory Management
The same instance of a property is shared across multiple widget instances.

Comparison Python / Kivy

Basic example

Let’s compare Python and Kivy properties by creating a Python class with ‘a’ as a float:

class MyClass(object):
    def __init__(self, a=1.0):
        super(MyClass, self).__init__()
        self.a = a

With Kivy, you can do:

class MyClass(EventDispatcher):
    a = NumericProperty(1.0)

Value checking

If you wanted to add a check such a minimum / maximum value allowed for a property, here is a possible implementation in Python:

class MyClass(object):
    def __init__(self, a=1):
        super(MyClass, self).__init__()
        self._a = 0
        self.a_min = 0
        self.a_max = 100
        self.a = a

    def _get_a(self):
        return self._a
    def _set_a(self, value):
        if value < self.a_min or value > self.a_max:
            raise ValueError('a out of bounds')
        self._a = a
    a = property(_get_a, _set_a)

The disadvantage is you have to do that work yourself. And it becomes laborious and complex if you have many properties. With Kivy, you can simplify like this:

class MyClass(EventDispatcher):
    a = BoundedNumericProperty(1, min=0, max=100)

That’s all!

Error Handling

If setting a value would otherwise raise a ValueError, you have two options to handle the error gracefully within the property. An errorvalue is a substitute for the invalid value. An errorhandler is a callable (single argument function or lambda) which can return a valid substitute.

errorhandler parameter:

# simply returns 0 if the value exceeds the bounds
bnp = BoundedNumericProperty(0, min=-500, max=500, errorvalue=0)

errorvalue parameter:

# returns a the boundary value when exceeded
bnp = BoundedNumericProperty(0, min=-500, max=500,
    errorhandler=lambda x: 500 if x > 500 else -500)

Conclusion

Kivy properties are easier to use than the standard ones. See the next chapter for examples of how to use them :)

Observe Properties changes

As we said in the beginning, Kivy’s Properties implement the Observer pattern. That means you can bind() to a property and have your own function called when the value changes.

Multiple ways are available to observe the changes.

Observe using bind()

You can observe a property change by using the bind() method, outside the class:

class MyClass(EventDispatcher):
    a = NumericProperty(1)

def callback(instance, value):
    print 'My callback is call from', instance,
    print 'and the a value changed to', value

ins = MyClass()
ins.bind(a=callback)

# At this point, any change to the a property will call your callback.
ins.a = 5    # callback called
ins.a = 5    # callback not called, because the value didnt change
ins.a = -1   # callback called

Observe using ‘on_<propname>’

If you created the class yourself, you can use the ‘on_<propname>’ callback:

class MyClass(EventDispatcher):
    a = NumericProperty(1)

    def on_a(self, instance, value):
        print 'My property a changed to', value

Warning

Be careful with ‘on_<propname>’. If you are creating such a callback on a property you are inherit, you must not forget to call the subclass function too.

class kivy.properties.Property

Bases: object

Base class for building more complex properties.

This class handles all the basic setters and getters, None type handling, the observer list and storage initialisation. This class should not be directly instantiated.

By default, a Property always takes a default value:

class MyObject(Widget):

    hello = Property('Hello world')

The default value must be a value that agrees with the Property type. For example, you can’t set a list to a StringProperty, because the StringProperty will check the default value.

None is a special case: you can set the default value of a Property to None, but you can’t set None to a property afterward. If you really want to do that, you must declare the Property with allownone=True:

class MyObject(Widget):

    hello = ObjectProperty(None, allownone=True)

# then later
a = MyObject()
a.hello = 'bleh' # working
a.hello = None # working too, because allownone is True.
Parameters :
errorhandler: callable

If set, must take a single argument and return a valid substitute value

errorvalue: object

If set, will replace an invalid property value (overrides errorhandler)

Changed in version 1.4.2: Parameters errorhandler and errorvalue added

bind()

Add a new observer to be called only when the value is changed.

dispatch()

Dispatch the value change to all observers.

Changed in version 1.1.0: The method is now accessible from Python.

This can be used to force the dispatch of the property, even if the value didn’t change:

button = Button()
# get the Property class instance
prop = button.property('text')
# dispatch this property on the button instance
prop.dispatch(button)
get()

Return the value of the property.

Link the instance with its real name.

Warning

Internal usage only.

When a widget is defined and uses a Property class, the creation of the property object happens, but the instance doesn’t know anything about its name in the widget class:

class MyWidget(Widget):
    uid = NumericProperty(0)

In this example, the uid will be a NumericProperty() instance, but the property instance doesn’t know its name. That’s why link() is used in Widget.__new__. The link function is also used to create the storage space of the property for this specific widget instance.

set()

Set a new value for the property.

unbind()

Remove the observer from our widget observer list.

class kivy.properties.NumericProperty

Bases: kivy.properties.Property

Property that represents a numeric value.

The NumericProperty accepts only int or float.

>>> wid = Widget()
>>> wid.x = 42
>>> print wid.x
42
>>> wid.x = "plop"
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "properties.pyx", line 93, in kivy.properties.Property.__set__
   File "properties.pyx", line 111, in kivy.properties.Property.set
   File "properties.pyx", line 159, in kivy.properties.NumericProperty.check
 ValueError: NumericProperty accept only int/float

Changed in version 1.4.1: NumericProperty can now accept custom text and tuple value to indicate a type, like “in”, “pt”, “px”, “cm”, “mm”, in the format: ‘10pt’ or (10, ‘pt’).

get_format()

Return the format used for Numeric calculation. Default is px (mean the value have not been changed at all). Otherwise, it can be one of ‘in’, ‘pt’, ‘cm’, ‘mm’.

class kivy.properties.StringProperty

Bases: kivy.properties.Property

Property that represents a string value.

Only a string or unicode is accepted.

class kivy.properties.ListProperty

Bases: kivy.properties.Property

Property that represents a list.

Only lists are allowed. Tuple or any other classes are forbidden.

class kivy.properties.ObjectProperty

Bases: kivy.properties.Property

Property that represents a Python object.

Parameters :
baseclass: object

This will be used for: isinstance(value, baseclass).

Warning

To mark the property as changed, you must reassign a new python object.

Changed in version 1.7.0.

class kivy.properties.BooleanProperty

Bases: kivy.properties.Property

Property that represents only a boolean value.

class kivy.properties.BoundedNumericProperty

Bases: kivy.properties.Property

Property that represents a numeric value within a minimum bound and/or maximum bound – within a numeric range.

Parameters :
min: numeric

If set, minimum bound will be used, with the value of min

max: numeric

If set, maximum bound will be used, with the value of max

bounds

Return min/max of the value.

New in version 1.0.9.

get_max()

Return the maximum value acceptable for the BoundedNumericProperty in obj. Return None if no maximum value is set. Check get_min for a usage example.

New in version 1.1.0.

get_min()

Return the minimum value acceptable for the BoundedNumericProperty in obj. Return None if no minimum value is set:

class MyWidget(Widget):
    number = BoundedNumericProperty(0, min=-5, max=5)

widget = MyWidget()
print widget.property('number').get_min(widget)
# will output -5

New in version 1.1.0.

set_max()

Change the maximum value acceptable for the BoundedNumericProperty, only for the obj instance. Set to None if you want to disable it. Check set_min for a usage example.

Warning

Changing the bounds doesn’t revalidate the current value.

New in version 1.1.0.

set_min()

Change the minimum value acceptable for the BoundedNumericProperty, only for the obj instance. Set to None if you want to disable it:

class MyWidget(Widget):
    number = BoundedNumericProperty(0, min=-5, max=5)

widget = MyWidget()
# change the minmium to -10
widget.property('number').set_min(widget, -10)
# or disable the minimum check
widget.property('number').set_min(widget, None)

Warning

Changing the bounds doesn’t revalidate the current value.

New in version 1.1.0.

class kivy.properties.OptionProperty

Bases: kivy.properties.Property

Property that represents a string from a predefined list of valid options.

If the string set in the property is not in the list of valid options (passed at property creation time), a ValueError exception will be raised.

Parameters :
options: list (not tuple.)

List of valid options

options

Return the options available.

New in version 1.0.9.

class kivy.properties.ReferenceListProperty

Bases: kivy.properties.Property

Property that allows the creaton of a tuple of other properties.

For example, if x and y are NumericProperty`s, we can create a :class:`ReferenceListProperty for the pos. If you change the value of pos, it will automatically change the values of x and y accordingly. If you read the value of pos, it will return a tuple with the values of x and y.

class kivy.properties.AliasProperty

Bases: kivy.properties.Property

Create a property with a custom getter and setter.

If you don’t find a Property class that fits to your needs, you can make your own by creating custom Python getter and setter methods.

Example from kivy/uix/widget.py:

def get_right(self):
    return self.x + self.width
def set_right(self, value):
    self.x = value - self.width
right = AliasProperty(get_right, set_right, bind=('x', 'width'))
Parameters :
getter: function

Function to use as a property getter

setter: function

Function to use as a property setter

bind: list/tuple

Properties to observe for changes, as property name strings

cache: boolean

If True, the value will be cached, until one of the binded elements will changes

Changed in version 1.4.0: Parameter cache added.

class kivy.properties.DictProperty

Bases: kivy.properties.Property

Property that represents a dict.

Only dict are allowed. Any other classes are forbidden.

class kivy.properties.VariableListProperty

Bases: kivy.properties.Property

A ListProperty that mimics the css way of defining numeric values such as padding, margin, etc.

Accepts a list of 1 or 2 (or 4 when length=4) Numeric arguments or a single Numeric argument.

VariableListProperty([1]) represents [1, 1, 1, 1]. VariableListProperty([1, 2]) represents [1, 2, 1, 2]. VariableListProperty([‘1px’, (2, ‘px’), 3, 4.0]) represents [1, 2, 3, 4.0]. VariableListProperty(5) represents [5, 5, 5, 5]. VariableListProperty(3, length=2) represents [3, 3].

Parameters :
length: int

The length of the list, can be 2 or 4.

New in version 1.7.0.