test-kivy-app/kivy_venv/lib/python3.11/site-packages/asynckivy/_event.py

58 lines
1.7 KiB
Python
Raw Permalink Normal View History

2024-09-15 17:57:02 +00:00
__all__ = ('event', )
import typing as T
import types
from functools import partial
from asyncgui import _current_task, _sleep_forever
@types.coroutine
def event(event_dispatcher, event_name, *, filter=None, stop_dispatching=False) -> T.Awaitable[tuple]:
'''
Returns an awaitable that can be used to wait for:
* a Kivy event to occur.
* a Kivy property's value to change.
.. code-block::
# Wait for a button to be pressed.
await event(button, 'on_press')
# Wait for an 'on_touch_down' event to occur.
__, touch = await event(widget, 'on_touch_down')
# Wait for 'widget.x' to change.
__, x = await ak.event(widget, 'x')
The ``filter`` parameter:
.. code-block::
# Wait for an 'on_touch_down' event to occur inside a widget.
__, touch = await event(widget, 'on_touch_down', filter=lambda w, t: w.collide_point(*t.opos))
# Wait for 'widget.x' to become greater than 100.
if widget.x <= 100:
await event(widget, 'x', filter=lambda __, x: x > 100)
The ``stop_dispatching`` parameter:
It only works for events not for properties.
See :ref:`kivys-event-system` for details.
'''
task = (yield _current_task)[0][0]
bind_id = event_dispatcher.fbind(event_name, partial(_callback, filter, task, stop_dispatching))
assert bind_id # check if binding succeeded
try:
return (yield _sleep_forever)[0]
finally:
event_dispatcher.unbind_uid(event_name, bind_id)
def _callback(filter, task, stop_dispatching, *args, **kwargs):
if (filter is None) or filter(*args, **kwargs):
task._step(*args)
return stop_dispatching