Quick search

Properties

The Properties classes are used when you create an 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 against validation constraints. For example, validation for an OptionProperty will make sure that the value is in a predefined list of possibilities. Validation for a 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 vs. Kivy

Basic example

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

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 for 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_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 = value
    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 the process:

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.

errorvalue parameter:

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

errorhandler parameter:

# returns 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.

There are multiple ways to observe the changes.

Observe using bind()

You can observe a property change by using the bind() method outside of 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 did not 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 inheriting, you must not forget to call the superclass function too.

Binding to properties of properties.

When binding to a property of a property, for example binding to a numeric property of an object saved in a object property, updating the object property to point to a new object will not re-bind the numeric property to the new object. For example:

<MyWidget>:
    Label:
        id: first
        text: 'First label'
    Label:
        id: second
        text: 'Second label'
    Button:
        label: first
        text: self.label.text
        on_press: self.label = second

When clicking on the button, although the label object property has changed to the second widget, the button text will not change because it is bound to the text property of the first label directly.

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 :
default:

Specifies the default value for the property.

**kwargs:

If the parameters include errorhandler, this should be a callable which must take a single argument and return a valid substitute value.

If the parameters include errorvalue, this should be an object. If set, it 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.

Parameters :
default: int or float, defaults to 0

Specifies the default value of the property.

>>> 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.

Parameters :
default: string, defaults to ‘’

Specifies the default value of the property.

class kivy.properties.ListProperty

Bases: kivy.properties.Property

Property that represents a list.

Parameters :
default: list, defaults to []

Specifies the default value of the property.

class kivy.properties.ObjectProperty

Bases: kivy.properties.Property

Property that represents a Python object.

Parameters :
default: object type

Specifies the default value of the property.

**kwargs: a list of keyword arguments

If kwargs includes a baseclass argument, this value will be used for validation: isinstance(value, kwargs[‘baseclass’]).

Warning

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

Changed in version 1.7.0: baseclass parameter added.

class kivy.properties.BooleanProperty

Bases: kivy.properties.Property

Property that represents only a boolean value.

Parameters :
default: boolean

Specifies the default value of the property.

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 :
default: numeric

Specifies the default value of the property.

**kwargs: a list of keyword arguments

If a min parameter is included, this specifies the minimum numeric value that will be accepted. If a max parameter is included, this specifies the maximum numeric value that will be accepted.

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 :
default: any valid type in the list of options

Specifies the default value of the property.

**kwargs: a list of keyword arguments

Should include an options parameter specifying a list (not tuple) 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 creation of a tuple of other properties.

For example, if x and y are NumericPropertys, we can create a 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.

Parameters :
default: dict, defaults to None

Specifies the default value of the property.

class kivy.properties.VariableListProperty

Bases: kivy.properties.Property

A ListProperty that allows you to work with a variable amount of list items and to expand them to the desired list size.

For example, GridLayout’s padding used to just accept one numeric value which was applied equally to the left, top, right and bottom of the GridLayout. Now padding can be given one, two or four values, which are expanded into a length four list [left, top, right, bottom] and stored in the property.

Parameters :
default: a default list of values

Specifies the default values for the list.

length: int, one of 2 or 4.

Specifies the length of the final list. The default list will be expanded to match a list of this length.

**kwargs: a list of keyword arguments

Not currently used.

Keeping in mind that the default list is expanded to a list of length 4, here are some examples of how VariabelListProperty’s are handled.

  • 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].

New in version 1.7.0.