Version

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)

Depth being tracked

Only the “top level” of a nested object is being tracked. For example:

my_list_prop = ListProperty([1, {'hi': 0}])
# Changing a top level element will trigger all `on_my_list_prop` callbacks
my_list_prop[0] = 4
# Changing a deeper element will be ignored by all `on_my_list_prop` callbacks
my_list_prop[1]['hi'] = 4

The same holds true for all container-type kivy properties.

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. The first option is to use an errorvalue parameter. An errorvalue is a substitute for the invalid value:

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

The second option in to use an errorhandler parameter. An errorhandler is a callable (single argument function or lambda) which can return a valid substitute:

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

Keyword arguments and __init__()

When working with inheritance, namely with the __init__() of an object that inherits from EventDispatcher e.g. a Widget, the properties protect you from a Python 3 object error. This error occurs when passing kwargs to the object instance through a super() call:

class MyClass(EventDispatcher):
    def __init__(self, **kwargs):
        super(MyClass, self).__init__(**kwargs)
        self.my_string = kwargs.get('my_string')

print(MyClass(my_string='value').my_string)

While this error is silenced in Python 2, it will stop the application in Python 3 with:

TypeError: object.__init__() takes no parameters

Logically, to fix that you’d either put my_string directly in the __init__() definition as a required argument or as an optional keyword argument with a default value i.e.:

class MyClass(EventDispatcher):
    def __init__(self, my_string, **kwargs):
        super(MyClass, self).__init__(**kwargs)
        self.my_string = my_string

or:

class MyClass(EventDispatcher):
    def __init__(self, my_string='default', **kwargs):
        super(MyClass, self).__init__(**kwargs)
        self.my_string = my_string

Alternatively, you could pop the key-value pair from the kwargs dictionary before calling super():

class MyClass(EventDispatcher):
    def __init__(self, **kwargs):
        self.my_string = kwargs.pop('my_string')
        super(MyClass, self).__init__(**kwargs)

Kivy properties are more flexible and do the required kwargs.pop() in the background automatically (within the super() call to EventDispatcher) to prevent this distraction:

class MyClass(EventDispatcher):
    my_string = StringProperty('default')
    def __init__(self, **kwargs):
        super(MyClass, self).__init__(**kwargs)

print(MyClass(my_string='value').my_string)

Conclusion

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

Observe Property 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

Note

Property objects live at the class level and manage the values attached to instances. Re-assigning at class level will remove the Property. For example, continuing with the code above, MyClass.a = 5 replaces the property object with a simple int.

Observe using ‘on_<propname>’

If you defined 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.

In 1.9.0, the rebind option has been introduced that will allow the automatic updating of the text when label is changed, provided it was enabled. See ObjectProperty.

class kivy.properties.Property(defaultvalue, **kw)

Bases: builtins.object

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

If the parameters include force_dispatch, it should be a boolean. If True, no value comparison will be done, so the property event will be dispatched even if the new value matches the old value (by default identical values are not dispatched to avoid infinite recursion in two-way binds). Be careful, this is for advanced use only.

comparator: callable or None

When not None, it’s called with two values to be compared. The function returns whether they are considered the same.

deprecated: bool

When True, a warning will be logged if the property is accessed or set. Defaults to False.

Changed in version 1.4.2: Parameters errorhandler and errorvalue added

Changed in version 1.9.0: Parameter force_dispatch added

Changed in version 1.11.0: Parameter deprecated added

bind(EventDispatcher obj, observer)

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

defaultvalue

defaultvalue: object

dispatch(EventDispatcher obj)

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)
Property.fbind(EventDispatcher obj, observer, int ref, tuple largs=

Similar to bind, except it doesn’t check if the observer already exists. It also expands and forwards largs and kwargs to the callback. funbind or unbind_uid should be called when unbinding. It returns a unique positive uid to be used with unbind_uid.

Property.funbind(EventDispatcher obj, observer, tuple largs=

Remove the observer from our widget observer list bound with fbind. It removes the first match it finds, as opposed to unbind which searches for all matches.

get(EventDispatcher obj)

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(EventDispatcher obj, value)

Set a new value for the property.

unbind(EventDispatcher obj, observer)

Remove the observer from our widget observer list.

unbind_uid(EventDispatcher obj, uid)

Remove the observer from our widget observer list bound with fbind using the uid.

class kivy.properties.NumericProperty(defaultvalue=0, **kw)

Bases: kivy.properties.Property

Parameters:
defaultvalue: 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(EventDispatcher obj)

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(defaultvalue='', **kw)

Bases: kivy.properties.Property

Parameters:
defaultvalue: string, defaults to ‘’

Specifies the default value of the property.

class kivy.properties.ListProperty(defaultvalue=0, **kw)

Bases: kivy.properties.Property

Parameters:
defaultvalue: list, defaults to []

Specifies the default value of the property.

Warning

When assigning a list to a ListProperty, the list stored in the property is a shallow copy of the list and not the original list. This can be demonstrated with the following example:

>>> class MyWidget(Widget):
>>>     my_list = ListProperty([])

>>> widget = MyWidget()
>>> my_list = [1, 5, {'hi': 'hello'}]
>>> widget.my_list = my_list
>>> print(my_list is widget.my_list)
False
>>> my_list.append(10)
>>> print(my_list, widget.my_list)
[1, 5, {'hi': 'hello'}, 10] [1, 5, {'hi': 'hello'}]

However, changes to nested levels will affect the property as well, since the property uses a shallow copy of my_list.

>>> my_list[2]['hi'] = 'bye'
>>> print(my_list, widget.my_list)
[1, 5, {'hi': 'bye'}, 10] [1, 5, {'hi': 'bye'}]
set(EventDispatcher obj, value)
class kivy.properties.ObjectProperty(defaultvalue=None, rebind=False, **kw)

Bases: kivy.properties.Property

Parameters:
defaultvalue: object type

Specifies the default value of the property.

rebind: bool, defaults to False

Whether kv rules using this object as an intermediate attribute in a kv rule, will update the bound property when this object changes.

That is the standard behavior is that if there’s a kv rule text: self.a.b.c.d, where a, b, and c are properties with rebind False and d is a StringProperty. Then when the rule is applied, text becomes bound only to d. If a, b, or c change, text still remains bound to d. Furthermore, if any of them were None when the rule was initially evaluated, e.g. b was None; then text is bound to b and will not become bound to d even when b is changed to not be None.

By setting rebind to True, however, the rule will be re-evaluated and all the properties rebound when that intermediate property changes. E.g. in the example above, whenever b changes or becomes not None if it was None before, text is evaluated again and becomes rebound to d. The overall result is that text is now bound to all the properties among a, b, or c that have rebind set to True.

**kwargs: a list of keyword arguments
baseclass

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.9.0: rebind has been introduced.

Changed in version 1.7.0: baseclass parameter added.

rebind

rebind: ‘int’

class kivy.properties.BooleanProperty(defaultvalue=True, **kw)

Bases: kivy.properties.Property

Parameters:
defaultvalue: boolean

Specifies the default value of the property.

class kivy.properties.BoundedNumericProperty(*largs, **kw)

Bases: kivy.properties.Property

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(EventDispatcher obj)

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(EventDispatcher obj)

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(EventDispatcher obj, value)

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(EventDispatcher obj, value)

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 minimum 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(*largs, **kw)

Bases: kivy.properties.Property

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.

For example:

class MyWidget(Widget):
    state = OptionProperty("None", options=["On", "Off", "None"])
options

Return the options available.

New in version 1.0.9.

class kivy.properties.ReferenceListProperty(*largs, **kw)

Bases: kivy.properties.Property

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.

For example:

class MyWidget(EventDispatcher):
    x = NumericProperty(0)
    y = NumericProperty(0)
    pos = ReferenceListProperty(x, y)
get(EventDispatcher obj)
set(EventDispatcher obj, _value)
setitem(EventDispatcher obj, key, value)
trigger_change(EventDispatcher obj, value)
class kivy.properties.AliasProperty(getter, setter=None, rebind=False, **kwargs)

Bases: kivy.properties.Property

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 where x and width are instances of NumericProperty:

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'])

If x were a non Kivy property then you have to return True from setter to dispatch new value of right:

def set_right(self, value):
    self.x = value - self.width
    return True

Usually bind list should contain all Kivy properties used in getter method. If you return True it will cause a dispatch which one should do when the property value has changed, but keep in mind that the property could already have dispatched the changed value if a kivy property the alias property is bound was set in the setter, causing a second dispatch if the setter returns True.

If you want to cache the value returned by getter then pass cache=True. This way getter will only be called if new value is set or one of the binded properties changes. In both cases new value of alias property will be cached again.

To make property readonly pass None as setter. This way AttributeError will be raised on every set attempt:

right = AliasProperty(get_right, None, bind=['x', 'width'], cache=True)
Parameters:
getter: function

Function to use as a property getter.

setter: function

Function to use as a property setter. Callbacks bound to the alias property won’t be called when the property is set (e.g. right = 10), unless the setter returns True.

bind: list/tuple

Properties to observe for changes as property name strings. Changing values of this properties will dispatch value of the alias property.

cache: boolean

If True, the value will be cached until one of the binded elements changes or if setter returns True.

rebind: bool, defaults to False

See ObjectProperty for details.

Changed in version 1.9.0: rebind has been introduced.

Changed in version 1.4.0: Parameter cache added.

dispatch(EventDispatcher obj)
get(EventDispatcher obj)
rebind

rebind: ‘int’

set(EventDispatcher obj, value)
trigger_change(EventDispatcher obj, value)
class kivy.properties.DictProperty(defaultvalue=0, rebind=False, **kw)

Bases: kivy.properties.Property

Parameters:
defaultvalue: dict, defaults to {}

Specifies the default value of the property.

rebind: bool, defaults to False

See ObjectProperty for details.

Changed in version 1.9.0: rebind has been introduced.

Warning

Similar to ListProperty, when assigning a dict to a DictProperty, the dict stored in the property is a shallow copy of the dict and not the original dict. See ListProperty for details.

rebind

rebind: ‘int’

set(EventDispatcher obj, value)
class kivy.properties.VariableListProperty(defaultvalue=None, length=4, **kw)

Bases: kivy.properties.Property

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.

length

length: ‘int’

class kivy.properties.ConfigParserProperty(defaultvalue, section, key, config, **kw)

Bases: kivy.properties.Property

of a ConfigParser as well as to bind the ConfigParser values to other properties.

A ConfigParser is composed of sections, where each section has a number of keys and values associated with these keys. ConfigParserProperty lets you automatically listen to and change the values of specified keys based on other kivy properties.

For example, say we want to have a TextInput automatically write its value, represented as an int, in the info section of a ConfigParser. Also, the textinputs should update its values from the ConfigParser’s fields. Finally, their values should be displayed in a label. In py:

class Info(Label):

    number = ConfigParserProperty(0, 'info', 'number', 'example',
                                  val_type=int, errorvalue=41)

    def __init__(self, **kw):
        super(Info, self).__init__(**kw)
        config = ConfigParser(name='example')

The above code creates a property that is connected to the number key in the info section of the ConfigParser named example. Initially, this ConfigParser doesn’t exist. Then, in __init__, a ConfigParser is created with name example, which is then automatically linked with this property. then in kv:

BoxLayout:
    TextInput:
        id: number
        text: str(info.number)
    Info:
        id: info
        number: number.text
        text: 'Number: {}'.format(self.number)

You’ll notice that we have to do text: str(info.number), this is because the value of this property is always an int, because we specified int as the val_type. However, we can assign anything to the property, e.g. number: number.text which assigns a string, because it is instantly converted with the val_type callback.

Note

If a file has been opened for this ConfigParser using read(), then write() will be called every property change, keeping the file updated.

Warning

It is recommend that the config parser object be assigned to the property after the kv tree has been constructed (e.g. schedule on next frame from init). This is because the kv tree and its properties, when constructed, are evaluated on its own order, therefore, any initial values in the parser might be overwritten by objects it’s bound to. So in the example above, the TextInput might be initially empty, and if number: number.text is evaluated before text: str(info.number), the config value will be overwritten with the (empty) text value.

Parameters:
default: object type

Specifies the default value for the key. If the parser associated with this property doesn’t have this section or key, it’ll be created with the current value, which is the default value initially.

section: string type

The section in the ConfigParser where the key / value will be written. Must be provided. If the section doesn’t exist, it’ll be created.

key: string type

The key in section section where the value will be written to. Must be provided. If the key doesn’t exist, it’ll be created and the current value written to it, otherwise its value will be used.

config: string or ConfigParser instance.

The ConfigParser instance to associate with this property if not None. If it’s a string, the ConfigParser instance whose name is the value of config will be used. If no such parser exists yet, whenever a ConfigParser with this name is created, it will automatically be linked to this property.

Whenever a ConfigParser becomes linked with a property, if the section or key doesn’t exist, the current property value will be used to create that key, otherwise, the existing key value will be used for the property value; overwriting its current value. You can change the ConfigParser associated with this property if a string was used here, by changing the name of an existing or new ConfigParser instance. Or through set_config().

**kwargs: a list of keyword arguments
val_type: a callable object

The key values are saved in the ConfigParser as strings. When the ConfigParser value is read internally and assigned to the property or when the user changes the property value directly, if val_type is not None, it will be called with the new value as input and it should return the value converted to the proper type accepted ny this property. For example, if the property represent ints, val_type can simply be int.

If the val_type callback raises a ValueError, errorvalue or errorhandler will be used if provided. Tip: the getboolean function of the ConfigParser might also be useful here to convert to a boolean type.

verify: a callable object

Can be used to restrict the allowable values of the property. For every value assigned to the property, if this is specified, verify is called with the new value, and if it returns True the value is accepted, otherwise, errorvalue or errorhandler will be used if provided or a ValueError is raised.

New in version 1.9.0.

set(EventDispatcher obj, value)
set_config(config)

Sets the ConfigParser object to be used by this property. Normally, the ConfigParser is set when initializing the Property using the config parameter.

Parameters:
config: A ConfigParser instance.

The instance to use for listening to and saving property value changes. If None, it disconnects the currently used ConfigParser.

class MyWidget(Widget):
    username = ConfigParserProperty('', 'info', 'name', None)

widget = MyWidget()
widget.property('username').set_config(ConfigParser())