Table Of Contents
- Event dispatcher
EventDispatcher
EventDispatcher.apply_property()
EventDispatcher.bind()
EventDispatcher.create_property()
EventDispatcher.dispatch()
EventDispatcher.dispatch_children()
EventDispatcher.dispatch_generic()
EventDispatcher.events()
EventDispatcher.fbind()
EventDispatcher.funbind()
EventDispatcher.get_property_observers()
EventDispatcher.getter()
EventDispatcher.is_event_type()
EventDispatcher.properties()
EventDispatcher.property()
EventDispatcher.proxy_ref
EventDispatcher.register_event_type()
EventDispatcher.setter()
EventDispatcher.unbind()
EventDispatcher.unbind_uid()
EventDispatcher.unregister_event_type()
EventDispatcher.unregister_event_types()
ObjectWithUid
Observable
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’sweakref
).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.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.Although
bind()
creates aWeakMethod
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 aWeakMethod
is saved. This is useful when there’s no risk of a memory leak by storing the callback directly.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 withunbind_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 nonEventDispatcher
based class used with the kv lang. SeeObservable
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 withbind()
as long as no keyword and positional arguments are provided tofunbind()
.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 ifbind()
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 theEventDispatcher
.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:
start with the prefix on_.
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.
- 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 withfbind()
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. SeeEventDispatcher
for details.New in version 1.9.0.
- bind(self, **kwargs)¶
- fbind(self, name, func, *largs, **kwargs)¶
-
Note
To keep backward compatibility with derived classes which may have inherited from
Observable
before, thefbind()
method was added. The default implementation offbind()
is to create a partial function that it passes to bind while saving the uid and largs/kwargs. However,funbind()
(andunbind_uid()
) are fairly inefficient since we have to first lookup this partial function using the largs/kwargs or uid and then callunbind()
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 withunbind_uid()
.
- funbind(self, name, func, *largs, **kwargs)¶
See
fbind()
andEventDispatcher.funbind()
.
- unbind(self, **kwargs)¶
- unbind_uid(self, name, uid)¶
See
fbind()
andEventDispatcher.unbind_uid()
.