Skip to content

Instantly share code, notes, and snippets.

@HeaTTheatR
Forked from gottadiveintopython/readme.txt
Created May 25, 2019 23:47
Show Gist options
  • Select an option

  • Save HeaTTheatR/3fad6402bdbb3ef2935fdd22628f7b56 to your computer and use it in GitHub Desktop.

Select an option

Save HeaTTheatR/3fad6402bdbb3ef2935fdd22628f7b56 to your computer and use it in GitHub Desktop.
async/await in Kivy
# -*- coding: utf-8 -*-
__all__ = ('start', 'sleep', 'event', )
import types
from functools import partial
from collections import namedtuple
from kivy.clock import Clock
CallbackParameter = namedtuple('CallbackParameter', ('args', 'kwargs', ))
def start(coro):
def step(*args, **kwargs):
try:
coro.send(CallbackParameter(args, kwargs))(step)
except StopIteration:
pass
try:
coro.send(None)(step)
except StopIteration:
pass
@types.coroutine
def sleep(duration):
# The partial() here looks meaningless. But this is needed in order
# to avoid weak reference
param = yield lambda step_coro: Clock.schedule_once(
partial(step_coro), duration)
return param.args[0]
class event:
def __init__(self, ed, name):
self.bind_id = None
self.ed = ed
self.name = name
def bind(self, step_coro):
self.bind_id = bind_id = self.ed.fbind(self.name, self.callback)
assert bind_id > 0 # check if binding succeeded
self.step_coro = step_coro
def callback(self, *args, **kwargs):
self.parameter = CallbackParameter(args, kwargs)
ed = self.ed
ed.unbind_uid(self.name, self.bind_id)
self.step_coro()
def __await__(self):
yield self.bind
return self.parameter
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.label import Label
from kivy.utils import get_color_from_hex
import asynckivy as ak
class TestApp(App):
def build(self):
return Label(text='Hello', markup=True, font_size='80sp',
outline_width=2,
outline_color=get_color_from_hex('#FFFFFF'),
color=get_color_from_hex('#000000'),
)
def on_start(self):
async def animate(label):
await ak.sleep(1.5)
while True:
label.outline_color = get_color_from_hex('#FFFFFF')
label.text = 'Do'
await ak.sleep(.5)
label.text = 'you'
await ak.sleep(.5)
label.text = 'like'
await ak.sleep(.5)
label.text = 'Kivy?'
await ak.sleep(2)
label.outline_color = get_color_from_hex('#FF5555')
label.text = 'Answer me!'
await ak.sleep(2)
label.outline_color = get_color_from_hex('#FFFF00')
label.text = 'Left-click to replay'
while True:
args, kwargs = await ak.event(label, 'on_touch_down')
touch = args[1]
if touch.button == 'left':
break
ak.start(animate(self.root))
if __name__ == '__main__':
TestApp().run()
@Isaiah-Gardner
Copy link

Thank you for this, found it extremely helpful in understanding how Kivy's Clock works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment