Sunday, 3 October 2021

How to async handle callback from keyboard hotkeys?

Need to register global hotkeys. For example, f4 and f8. With keyboard library while first callback didn't return, the next won't call.

Another words, logs like this

pressed f4
end for f4
pressed f8
end for f8

But I want to like this

pressed f4
pressed f8
end for f4
end for f8

Demo code

# pip install keyboard
from keyboard import add_hotkey, wait
from time import sleep

def on_callback(key):
    print('pressed', key)
    sleep(5) # emulate long run task
    print('end for', key)

add_hotkey("f4", lambda: on_callback("f4"))
add_hotkey("f8", lambda: on_callback("f8"))

wait('esc')

I tried to use asyncio, but nothing changed

pressed f4
end for f4
pressed f8
end for f8
from keyboard import add_hotkey, wait
import asyncio

async def on_callback(key):
    print('pressed', key)
    await asyncio.sleep(5) # emulate long run task
    print('end for', key)

add_hotkey("f4", lambda: asyncio.run(on_callback("f4")))
add_hotkey("f8", lambda: asyncio.run(on_callback("f8")))

wait('esc')

Update

Keyboard library's developer gave advise to use call_later function that create new thread for each callback and it's works like I want.

But is there way to do such task in the same thread (use asyncio)? I didn't succeed.

# example with 'call_later' function
from keyboard import add_hotkey, wait, call_later
from time import sleep

def on_callback(key):
    print('pressed', key)
    sleep(5) # emulate long run task
    print('end for', key)

add_hotkey("f4", lambda: call_later(on_callback, args=("f4",)))
add_hotkey("f8", lambda: call_later(on_callback, args=("f8",)))

wait('esc')


from How to async handle callback from keyboard hotkeys?

No comments:

Post a Comment