Версия 2.1.0

Quick search

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() и предназначен для более опытных пользователей и внутреннего использования. Его можно использовать, если соблюдаются следующие условия:

  1. В отличие от bind(), он не проверяет, не была ли эта функция и аргументы largs/kwargs уже привязаны к этому имени. Поэтому повторное привязывание того же обратного вызова многократно добавит его.

  2. В отличие от bind(), которая создает WeakMethod обратного вызова при привязке к событию или свойству, этот метод сохраняет обратный вызов непосредственно, если не передан ключевой аргумент ref со значением True, и затем сохраняется WeakMethod. Это полезно, когда нет риска утечки памяти при сохранении обратного вызова напрямую.

  3. Этот метод возвращает уникальное положительное число, если 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)

Регистрирует тип события в диспетчере.

Регистрация типов событий позволяет диспетчеру проверять имена обработчиков событий при их присоединении и искать подходящие обработчики в подключенных объектах. Каждое объявление типа события должно:

  1. начинаться с префикса on_.

  2. иметь обработчик по умолчанию в классе.

Пример создания пользовательского события:

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() на функции, привязанной с использованием fbind(), если эта функция изначально была привязана без ключевых и позиционных аргументов. В противном случае отмена привязки функции завершится ошибкой, и вам следует использовать вместо этого funbind().

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)

См. EventDispatcher.fbind().

Примечание

Чтобы обеспечить обратную совместимость с производными классами, которые могли унаследоваться от 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)

См. fbind() и EventDispatcher.unbind_uid().