Table Of Contents
Диспетчер событий¶
Все объекты, которые генерируют события в Kivy, реализуют EventDispatcher
, который предоставляет согласованный интерфейс для регистрации и управления обработчиками событий.
Изменено в версии 1.0.9: Обнаружение свойств и методов были перенесены из
Widget
в EventDispatcher
.
- class kivy.event.EventDispatcher(**kwargs)¶
Базовый класс:
kivy.event.ObjectWithUid
См. описание модуля для использования.
- apply_property(**kwargs)¶
Добавляет свойства в класс во время выполнения. Функция принимает именованные аргументы в форме имя_свойства=свойство, где свойство является экземпляром
Property
, а имя_свойства - это имя атрибута свойства.Новое в версии 1.9.1.
Предупреждение
Этот метод не рекомендуется для общего использования, потому что вам следует объявлять свойства в своем классе, а не использовать этот метод.
Например:
>>> 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(**kwargs)¶
Привязать тип события или свойство к обратному вызову.
Использование:
# Со свойствами def my_x_callback(obj, value): print('на объекте', obj, 'x изменилось на', value) def my_width_callback(obj, value): print('на объекте', obj, 'width изменилось на', value) self.bind(x=my_x_callback, width=my_width_callback) # С событием def my_press_callback(obj): print('событие на объекте', obj) self.bind(on_press=my_press_callback)
В общем случае обратные вызовы для свойств вызываются с 2 аргументами (объектом и новым значением свойства), а обратные вызовы событий - с одним аргументом (объектом). Приведенный выше пример иллюстрирует это.
Следующий пример демонстрирует различные способы использования функции bind в полноценном приложении:
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()
Если обратный вызов уже был связан с определенным событием или свойством, он не будет добавлен повторно.
При привязке метода к событию или свойству сохраняется
kivy.weakmethod.WeakMethod
обратного вызова. Вместо обычной ссылки сохраняется слабая ссылка на экземпляр (см.weakref
в Python).Это имеет два последствия.
Первое - привязка не помешает сборке мусора для объекта метода. Клиент должен сохранить ссылку на экземпляр для желаемого времени жизни. Ссылка на обратный вызов молча удаляется, если она становится недействительной.
Второе - при использовании декорированного метода, например:
@my_decorator def callback(self, *args): pass
Декоратор (
my_decorator
здесь) должен использовать wraps внутри.
- create_property(unicode name, value=None, default_value=True, *largs, **kwargs)¶
Создать новое свойство во время выполнения.
Добавлено в версии 1.0.9.
Изменено в версии 1.8.0: добавлен параметр value, который можно использовать для установки значения по умолчанию для свойства. Кроме того, тип значения используется для создания специализированного свойства.
Изменено в версии 1.9.0: Ранее, если value было типа bool, создавалось NumericProperty, теперь создается BooleanProperty.
Также, теперь при создании свойства передаются как позиционные, так и ключевые аргументы.
Изменено в версии 2.0.0: добавлен параметр default_value.
Предупреждение
Эта функция предназначена для Kivy, не используйте ее в своем коде. Вы должны объявить свойство в своем классе, а не использовать этот метод.
- Parameters
- name: строка
Имя свойства
- value: объект, необязательно
Значение по умолчанию для свойства. Тип также используется для создания более подходящих типов свойств. По умолчанию - None.
- default_value: логическое, True по умолчанию
Если True, value будет значением по умолчанию для свойства. В противном случае свойство будет инициализировано нормальным значением по умолчанию для типа свойства и затем установлено в
value
.
>>> mywidget = Widget() >>> mywidget.create_property('custom') >>> mywidget.custom = True >>> print(mywidget.custom) True
- dispatch(event_type, *largs, **kwargs)¶
Рассылка события по всем обработчикам, добавленным с помощью методов bind/fbind(). Как только один из обработчиков вернет True, рассылка прекращается.
Функция собирает все позиционные и ключевые аргументы и передает их обработчикам.
Примечание
Обработчики вызываются в обратном порядке, чем они были зарегистрированы с помощью
bind()
.- Parameters
- event_type: строка
имя события для рассылки.
Изменено в версии 1.9.0: Добавлена возможность сбора и передачи ключевых аргументов. Ранее собирались и передавались только позиционные аргументы.
- dispatch_children(event_type, *largs, **kwargs)¶
- dispatch_generic(event_type, *largs, **kwargs)¶
- events()¶
Возвращает все события в классе. Может использоваться для интроспекции.
Добавлено в версии 1.8.0.
- fbind(name, func, *largs, **kwargs)¶
Метод для продвинутой и, как правило, более быстрой привязки. Этот метод отличается от
bind()
и предназначен для более опытных пользователей и внутреннего использования. Его можно использовать, если соблюдаются следующие условия:В отличие от
bind()
, он не проверяет, не была ли эта функция и аргументы largs/kwargs уже привязаны к этому имени. Поэтому повторное привязывание того же обратного вызова многократно добавит его.В отличие от
bind()
, которая создаетWeakMethod
обратного вызова при привязке к событию или свойству, этот метод сохраняет обратный вызов непосредственно, если не передан ключевой аргумент ref со значением True, и затем сохраняетсяWeakMethod
. Это полезно, когда нет риска утечки памяти при сохранении обратного вызова напрямую.Этот метод возвращает уникальное положительное число, если name было найдено и привязано, и 0 в противном случае. В отличие от
bind()
, если свойство name не найдено, он не вызывает исключение. Если значение отлично от нуля, возвращаемый uid уникален для этого имени и обратного вызова и может использоваться сunbind_uid()
для отвязки.
При привязке обратного вызова с использованием largs и/или kwargs,
funbind()
должен использоваться для отвязки. Если не предоставлены largs и kwargs, можно также использоватьunbind()
.unbind_uid()
может использоваться в любом из этих случаев.Этот метод передает все захваченные позиционные и/или ключевые аргументы в обратный вызов, устраняя необходимость вызывать partial. При вызове обратного вызова сначала передаются расширенные largs, за которыми следует экземпляр/значение (только экземпляр для kwargs), а затем расширенные kwargs.
Ниже приведен пример использования, аналогичный примеру в
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')
Примечание
Поскольку kv-язык использует этот метод для привязки, его необходимо реализовать, вместо
bind()
, при создании класса, не основанного наEventDispatcher
, используемого с kv-языком. См.Observable
в качестве примера.Новое в версии 1.9.0.
Изменено в версии 1.9.1: Добавлен ключевой аргумент ref.
- funbind(name, func, *largs, **kwargs)¶
-
Аналогично
fbind()
.При отвязке
unbind()
будет отвязывать все обратные вызовы, которые совпадают с обратным вызовом, в то время как этот метод будет отвязывать только первый.Для отвязывания необходимо передать те же позиционные и ключевые аргументы, что и при использовании
fbind()
.Примечание
Безопасно использовать
funbind()
для отвязки функции, привязанной с помощьюbind()
, до тех пор, пока не предоставлены ключевые и позиционные аргументыfunbind()
.Новое в версии 1.9.0.
- get_property_observers(name, args=False)¶
-
Возвращает список методов, привязанных к свойству/событию, переданному в аргументе name:
widget_instance.get_property_observers('on_release')
- Parameters
-
- name: str
-
Имя события или свойства.
- args: bool
-
Возвращать ли связанные аргументы. Для совместимости будут возвращаться только функции обратного вызова, а не предоставленные им аргументы, когда args равно False.
Если True, каждый элемент в списке будет представлен в виде 5-кортежа (callback, largs, kwargs, is_ref, uid), где is_ref указывает, является ли callback слабой ссылкой, а uid - это UID, предоставленный
fbind()
, или None, если использовалсяbind()
. По умолчанию False.
- Returns
-
Список связанных функций обратного вызова. См. args для деталей.
Новое в версии 1.8.0.
- getter(name)¶
-
Возвращает геттер свойства.
Добавлено в версии 1.0.9.
- is_event_type(event_type)¶
-
Возвращает True, если event_type уже зарегистрировано.
Добавлено в версии 1.0.4.
- properties() dict ¶
-
Возвращает все свойства в классе в виде словаря ключ/класс свойства. Может использоваться для интроспекции.
Добавлено в версии 1.0.9.
- property(name, quiet=False)¶
-
Получает экземпляр свойства по имени свойства. Если quiet равно True, вместо возникновения исключения при отсутствии свойства с именем name возвращается None. По умолчанию False.
Добавлено в версии 1.0.9.
- Returns
-
Экземпляр, производный от
Property
, соответствующий имени.
Изменено в версии 1.9.0: Добавлен параметр quiet.
- proxy_ref¶
-
Возвращает ссылку
WeakProxy
наEventDispatcher
.Добавлено в версии 1.9.0.
Изменено в версии 2.0.0: Ранее он просто возвращал сам себя, теперь он действительно возвращает
WeakProxy
.
- register_event_type(event_type)¶
-
Регистрирует тип события в диспетчере.
Регистрация типов событий позволяет диспетчеру проверять имена обработчиков событий при их присоединении и искать подходящие обработчики в подключенных объектах. Каждое объявление типа события должно:
начинаться с префикса on_.
иметь обработчик по умолчанию в классе.
Пример создания пользовательского события:
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('мое событие swipe вызвано', largs) w = MyWidget() w.dispatch('on_swipe')
- setter(name)¶
-
Возвращает установщик свойства. Используйте: instance.setter(‘name’). Установщик представляет собой удобную функцию обратного вызова, полезную, если вы хотите прямо привязать одно свойство к другому. Он возвращает частичную функцию, которая будет принимать аргументы (obj, value) и приведет к установке свойства ‘name’ объекта в значение value.
Добавлено в версии 1.0.9.
Например, чтобы привязать number2 к number1 в Python, вы можете сделать следующее:
class ExampleWidget(Widget): number1 = NumericProperty(None) number2 = NumericProperty(None) def __init__(self, **kwargs): super(ExampleWidget, self).__init__(**kwargs) self.bind(number1=self.setter('number2'))
Это эквивалентно привязке в KV-файле:
<ExampleWidget>: number2: self.number1
- unbind(**kwargs)¶
-
Отменяет привязку свойств от функций обратного вызова с аналогичным использованием
bind()
.Если функция обратного вызова была привязана к определенному событию или свойству несколько раз, будет отменена только первая привязка.
- unbind_uid(name, uid)¶
-
Использует uid, возвращенный
fbind()
, чтобы отменить привязку обратного вызова.Этот метод гораздо более эффективен, чем
funbind()
. Если uid вычисляется как False (например, 0), вызывается ValueError. Кроме того, этим методом можно отменить привязку только функций, привязанных с помощьюfbind()
.Поскольку каждый вызов
fbind()
генерирует уникальный uid, будет удалена только одна привязка. Если uid не найден среди функций обратного вызова, не вызывается ошибок.Например:
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('Привязка не удалась'). ... btn6.unbind_uid('on_press', uid)
Добавлено в версии 1.9.0.
- unregister_event_type(event_type)¶
-
Удаляет тип события из диспетчера.
Если тип события не зарегистрирован, ничего не произойдет.
Добавлено в версии 1.9.0.
- unregister_event_types(self, event_type)¶
- class kivy.event.ObjectWithUid¶
Базовый класс:
builtins.object
(внутренний) Этот класс помогает предоставить уникальные идентификаторы для экземпляров классов. Не предназначен для прямого использования.
- class kivy.event.Observable¶
Базовый клас:
kivy.event.ObjectWithUid
Observable
- это заглушка, определяющая методы, необходимые для привязки. Примером класса, реализующего интерфейс привязки, являетсяEventDispatcher
. См.EventDispatcher
для подробностей.Добавлено в версии 1.9.0.
- bind(**kwargs)¶
- fbind(name, func, *largs, **kwargs)¶
-
Примечание
Чтобы обеспечить обратную совместимость с производными классами, которые могли унаследоваться от
Observable
до этого, был добавлен методfbind()
. Реализация по умолчаниюfbind()
заключается в создании частичной функции, которую она передает в привязку, сохраняя uid и largs/kwargs. Однакоfunbind()
(иunbind_uid()
) довольно неэффективны, так как сначала нам нужно найти эту частичную функцию, используя largs/kwargs или uid, а затем вызватьunbind()
на возвращенной функции. Рекомендуется переопределить эти методы в производных классах для непосредственной привязки для повышения производительности.Аналогично
EventDispatcher.fbind()
, этот метод возвращает 0 в случае неудачи и положительный уникальный uid в случае успеха. Этот uid можно использовать сunbind_uid()
.
- funbind(name, func, *largs, **kwargs)¶
См.
fbind()
иEventDispatcher.funbind()
.
- unbind(**kwargs)¶
- unbind_uid(name, uid)¶