Version

Quick search

Event dispatcher

All objects that produce events in Kivy implement the EventDispatcher which provides a consistent interface for registering and manipulating event handlers.

Changed in version 1.0.9: Property discovery and methods have been moved from the Widget to the EventDispatcher.

class kivy.event.EventDispatcher(**kwargs)

Bases: kivy.event.ObjectWithUid

See the module docstring for usage.

apply_property(self, **kwargs)

Adds properties at runtime to the class. The function accepts keyword arguments of the form prop_name=prop, where prop is a Property instance and prop_name is the name of the attribute of the property.

New in version 1.9.1.

Warning

This method is not recommended for common usage because you should declare the properties in your class instead of using this method.

For example:

>>> print(wid.property('sticks', quiet=True))
None
>>> wid.apply_property(sticks=ObjectProperty(55, max=10))
>>> print(wid.property('sticks', quiet=True))
<kivy.properties.ObjectProperty object at 0x04303130>
bind(self, **kwargs)

Bind an event type or a property to a callback.

Usage:

# With properties
def my_x_callback(obj, value):
    print('on object', obj, 'x changed to', value)
def my_width_callback(obj, value):
    print('on object', obj, 'width changed to', value)
self.bind(x=my_x_callback, width=my_width_callback)

# With event
def my_press_callback(obj):
    print('event on object', obj)
self.bind(on_press=my_press_callback)

In general, property callbacks are called with 2 arguments (the object and the property’s new value) and event callbacks with one argument (the object). The example above illustrates this.

The following example demonstrates various ways of using the bind function in a complete application:

from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.uix.button import Button
from functools import partial


class DemoBox(BoxLayout):
    """
    This class demonstrates various techniques that can be used for binding to
    events. Although parts could me made more optimal, advanced Python concepts
    are avoided for the sake of readability and clarity.
    """
    def __init__(self, **kwargs):
        super(DemoBox, self).__init__(**kwargs)
        self.orientation = "vertical"

        # We start with binding to a normal event. The only argument
        # passed to the callback is the object which we have bound to.
        btn = Button(text="Normal binding to event")
        btn.bind(on_press=self.on_event)

        # Next, we bind to a standard property change event. This typically
        # passes 2 arguments: the object and the value
        btn2 = Button(text="Normal binding to a property change")
        btn2.bind(state=self.on_property)

        # Here we use anonymous functions (a.k.a lambdas) to perform binding.
        # Their advantage is that you can avoid declaring new functions i.e.
        # they offer a concise way to "redirect" callbacks.
        btn3 = Button(text="Using anonymous functions.")
        btn3.bind(on_press=lambda x: self.on_event(None))

        # You can also declare a function that accepts a variable number of
        # positional and keyword arguments and use introspection to determine
        # what is being passed in. This is very handy for debugging as well
        # as function re-use. Here, we use standard event binding to a function
        # that accepts optional positional and keyword arguments.
        btn4 = Button(text="Use a flexible function")
        btn4.bind(on_press=self.on_anything)

        # Lastly, we show how to use partial functions. They are sometimes
        # difficult to grasp, but provide a very flexible and powerful way to
        # reuse functions.
        btn5 = Button(text="Using partial functions. For hardcores.")
        btn5.bind(on_press=partial(self.on_anything, "1", "2", monthy="python"))

        for but in [btn, btn2, btn3, btn4, btn5]:
            self.add_widget(but)

    def on_event(self, obj):
        print("Typical event from", obj)

    def on_property(self, obj, value):
        print("Typical property change from", obj, "to", value)

    def on_anything(self, *args, **kwargs):
        print('The flexible function has *args of', str(args),
            "and **kwargs of", str(kwargs))


class DemoApp(App):
    def build(self):
        return DemoBox()

if __name__ == "__main__":
    DemoApp().run()

If a callback has already been bound to a given event or property, it won’t be added again.

When binding a method to an event or property, a kivy.weakmethod.WeakMethod of the callback is saved. That is, rather than storing a regular reference, it stores both a weak reference to the instance (see Python’s weakref).

This has two consequences.

The first is that the binding will not prevent garbage collection of the method’s object. The client must maintain a reference to the instance for the desired lifetime. The callback reference is silently removed if it becomes invalid.

The second is that when using a decorated method e.g.:

@my_decorator
def callback(self, *args):
    pass

the decorator (my_decorator here) must use wraps internally.

create_property(self, unicode name, value=None, default_value=True, *largs, **kwargs)

Create a new property at runtime.

New in version 1.0.9.

Changed in version 1.8.0: value parameter added, can be used to set the default value of the property. Also, the type of the value is used to specialize the created property.

Changed in version 1.9.0: In the past, if value was of type bool, a NumericProperty would be created, now a BooleanProperty is created.

Also, now and positional and keyword arguments are passed to the property when created.

Changed in version 2.0.0: default_value has been added.

Warning

This function is designed for the Kivy language, don’t use it in your code. You should declare the property in your class instead of using this method.

Parameters:
name: string

Name of the property

value: object, optional

Default value of the property. Type is also used for creating more appropriate property types. Defaults to None.

default_value: bool, True by default

If True, value will be the default for the property. Otherwise, the property will be initialized with the the property type’s normal default value, and subsequently set to value.

>>> mywidget = Widget()
>>> mywidget.create_property('custom')
>>> mywidget.custom = True
>>> print(mywidget.custom)
True
dispatch(self, event_type, *largs, **kwargs)

Dispatch an event across all the handlers added in bind/fbind(). As soon as a handler returns True, the dispatching stops.

The function collects all the positional and keyword arguments and passes them on to the handlers.

Note

The handlers are called in reverse order than they were registered with bind().

Parameters:
event_type: str

the event name to dispatch.

Changed in version 1.9.0: Keyword arguments collection and forwarding was added. Before, only positional arguments would be collected and forwarded.

dispatch_children(self, event_type, *largs, **kwargs)
dispatch_generic(self, event_type, *largs, **kwargs)
events(self)

Return all the events in the class. Can be used for introspection.

New in version 1.8.0.

fbind(self, name, func, *largs, **kwargs)

A method for advanced, and typically faster binding. This method is different than bind() and is meant for more advanced users and internal usage. It can be used as long as the following points are heeded.

  1. As opposed to bind(), it does not check that this function and largs/kwargs has not been bound before to this name. So binding the same callback multiple times will just keep adding it.

  2. Although bind() creates a WeakMethod of the callback when binding to an event or property, this method stores the callback directly, unless a keyword argument ref with value True is provided and then a WeakMethod is saved. This is useful when there’s no risk of a memory leak by storing the callback directly.

  3. This method returns a unique positive number if name was found and bound, and 0, otherwise. It does not raise an exception, like bind() if the property name is not found. If not zero, the uid returned is unique to this name and callback and can be used with unbind_uid() for unbinding.

When binding a callback with largs and/or kwargs, funbind() must be used for unbinding. If no largs and kwargs are provided, unbind() may be used as well. unbind_uid() can be used in either case.

This method passes on any caught positional and/or keyword arguments to the callback, removing the need to call partial. When calling the callback the expended largs are passed on followed by instance/value (just instance for kwargs) followed by expended kwargs.

Following is an example of usage similar to the example in bind():

class DemoBox(BoxLayout):

    def __init__(self, **kwargs):
        super(DemoBox, self).__init__(**kwargs)
        self.orientation = "vertical"

        btn = Button(text="Normal binding to event")
        btn.fbind('on_press', self.on_event)

        btn2 = Button(text="Normal binding to a property change")
        btn2.fbind('state', self.on_property)

        btn3 = Button(text="A: Using function with args.")
        btn3.fbind('on_press', self.on_event_with_args, 'right',
                       tree='birch', food='apple')

        btn4 = Button(text="Unbind A.")
        btn4.fbind('on_press', self.unbind_a, btn3)

        btn5 = Button(text="Use a flexible function")
        btn5.fbind('on_press', self.on_anything)

        btn6 = Button(text="B: Using flexible functions with args. For hardcores.")
        btn6.fbind('on_press', self.on_anything, "1", "2", monthy="python")

        btn7 = Button(text="Force dispatch B with different params")
        btn7.fbind('on_press', btn6.dispatch, 'on_press', 6, 7, monthy="other python")

        for but in [btn, btn2, btn3, btn4, btn5, btn6, btn7]:
            self.add_widget(but)

    def on_event(self, obj):
        print("Typical event from", obj)

    def on_event_with_args(self, side, obj, tree=None, food=None):
        print("Event with args", obj, side, tree, food)

    def on_property(self, obj, value):
        print("Typical property change from", obj, "to", value)

    def on_anything(self, *args, **kwargs):
        print('The flexible function has *args of', str(args),
            "and **kwargs of", str(kwargs))
        return True

    def unbind_a(self, btn, event):
        btn.funbind('on_press', self.on_event_with_args, 'right',
                        tree='birch', food='apple')

Note

Since the kv lang uses this method to bind, one has to implement this method, instead of bind() when creating a non EventDispatcher based class used with the kv lang. See Observable for an example.

New in version 1.9.0.

Changed in version 1.9.1: The ref keyword argument has been added.

funbind(self, name, func, *largs, **kwargs)

Similar to fbind().

When unbinding, unbind() will unbind all callbacks that match the callback, while this method will only unbind the first.

To unbind, the same positional and keyword arguments passed to fbind() must be passed on to funbind.

Note

It is safe to use funbind() to unbind a function bound with bind() as long as no keyword and positional arguments are provided to funbind().

New in version 1.9.0.

get_property_observers(self, name, args=False)

Returns a list of methods that are bound to the property/event passed as the name argument:

widget_instance.get_property_observers('on_release')
Parameters:
name: str

The name of the event or property.

args: bool

Whether to return the bound args. To keep compatibility, only the callback functions and not their provided args will be returned in the list when args is False.

If True, each element in the list is a 5-tuple of (callback, largs, kwargs, is_ref, uid), where is_ref indicates whether callback is a weakref, and uid is the uid given by fbind(), or None if bind() was used. Defaults to False.

Returns:

The list of bound callbacks. See args for details.

New in version 1.8.0.

Changed in version 1.9.0: args has been added.

getter(self, name)

Return the getter of a property.

New in version 1.0.9.

is_event_type(self, event_type)

Return True if the event_type is already registered.

New in version 1.0.4.

properties(self) dict

Return all the properties in the class in a dictionary of key/property class. Can be used for introspection.

New in version 1.0.9.

property(self, name, quiet=False)

Get a property instance from the property name. If quiet is True, None is returned instead of raising an exception when name is not a property. Defaults to False.

New in version 1.0.9.

Returns:

A Property derived instance corresponding to the name.

Changed in version 1.9.0: quiet was added.

proxy_ref

Returns a WeakProxy reference to the EventDispatcher.

New in version 1.9.0.

Changed in version 2.0.0: Previously it just returned itself, now it actually returns a WeakProxy.

register_event_type(self, event_type)

Register an event type with the dispatcher.

Registering event types allows the dispatcher to validate event handler names as they are attached and to search attached objects for suitable handlers. Each event type declaration must:

  1. start with the prefix on_.

  2. have a default handler in the class.

Example of creating a custom event:

class MyWidget(Widget):
    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)
        self.register_event_type('on_swipe')

    def on_swipe(self):
        pass

def on_swipe_callback(*largs):
    print('my swipe is called', largs)
w = MyWidget()
w.dispatch('on_swipe')
setter(self, name)

Return the setter of a property. Use: instance.setter(‘name’). The setter is a convenient callback function useful if you want to directly bind one property to another. It returns a partial function that will accept (obj, value) args and results in the property ‘name’ of instance being set to value.

New in version 1.0.9.

For example, to bind number2 to number1 in python you would do:

class ExampleWidget(Widget):
    number1 = NumericProperty(None)
    number2 = NumericProperty(None)

    def __init__(self, **kwargs):
        super(ExampleWidget, self).__init__(**kwargs)
        self.bind(number1=self.setter('number2'))

This is equivalent to kv binding:

<ExampleWidget>:
    number2: self.number1
unbind(self, **kwargs)

Unbind properties from callback functions with similar usage as bind().

If a callback has been bound to a given event or property multiple times, only the first occurrence will be unbound.

Note

It is safe to use unbind() on a function bound with fbind() as long as that function was originally bound without any keyword and positional arguments. Otherwise, the function will fail to be unbound and you should use funbind() instead.

unbind_uid(self, name, uid)

Uses the uid returned by fbind() to unbind the callback.

This method is much more efficient than funbind(). If uid evaluates to False (e.g. 0) a ValueError is raised. Also, only callbacks bound with fbind() can be unbound with this method.

Since each call to fbind() will generate a unique uid, only one callback will be removed. If uid is not found among the callbacks, no error is raised.

E.g.:

btn6 = Button(text="B: Using flexible functions with args. For hardcores.")
uid = btn6.fbind('on_press', self.on_anything, "1", "2", monthy="python")
if not uid:
    raise Exception('Binding failed').
...
btn6.unbind_uid('on_press', uid)

New in version 1.9.0.

unregister_event_type(self, event_type)

Unregister an event type in the dispatcher.

Changed in version 2.1.0: Method renamed from unregister_event_types to unregister_event_type.

unregister_event_types(self, event_type)
class kivy.event.ObjectWithUid

Bases: builtins.object

(internal) This class assists in providing unique identifiers for class instances. It is not intended for direct usage.

class kivy.event.Observable

Bases: kivy.event.ObjectWithUid

Observable is a stub class defining the methods required for binding. EventDispatcher is (the) one example of a class that implements the binding interface. See EventDispatcher for details.

New in version 1.9.0.

bind(self, **kwargs)
fbind(self, name, func, *largs, **kwargs)

See EventDispatcher.fbind().

Note

To keep backward compatibility with derived classes which may have inherited from Observable before, the fbind() method was added. The default implementation of fbind() is to create a partial function that it passes to bind while saving the uid and largs/kwargs. However, funbind() (and unbind_uid()) are fairly inefficient since we have to first lookup this partial function using the largs/kwargs or uid and then call unbind() on the returned function. It is recommended to overwrite these methods in derived classes to bind directly for better performance.

Similarly to EventDispatcher.fbind(), this method returns 0 on failure and a positive unique uid on success. This uid can be used with unbind_uid().

funbind(self, name, func, *largs, **kwargs)

See fbind() and EventDispatcher.funbind().

unbind(self, **kwargs)
unbind_uid(self, name, uid)

See fbind() and EventDispatcher.unbind_uid().