How to call an async function from a tkinter button
Asked Answered
D

1

0

I want to call an asynchronous function from a tkinter button

import asyncio
import time
import tkinter as tk

async def gui():
    root = tk.Tk()
    timer = tk.Button(root, text='Timer', command=lambda: asyncio.run(wait()))
    # timer = tk.Button(root, text='Timer', command=wait())
    timer.pack()
    root.mainloop()

async def sleep():
    await asyncio.sleep(1)

async def wait():
    start = time.time()
    await sleep()
    print(f'Elapsed: {time.time() - start}')

async def main():
    await wait()

asyncio.run(main())
asyncio.run(gui())

If I use the line

    timer = tk.Button(root, text='Timer', command=wait())

I get the error

coroutine 'wait' was never awaited

but if I use the line

    timer = tk.Button(root, text='Timer', command=lambda: asyncio.run(wait()))

I get the error

asyncio.run() cannot be called from a running event loop

What's the resolution of this problem?

Driftwood answered 30/11, 2023 at 14:13 Comment(0)
D
1

The essence of this is to understand which functions come under the async umbrella. This is simpler and resolves all the issues. Note that only the sleep function is asynchronous, and the wait function contains the async call

asyncio.run(sleep())

The code is now:

import asyncio
import time
import tkinter as tk

def gui():
    root = tk.Tk()
    timer = tk.Button(root, text="Timer", command=wait)
    timer.pack()
    root.mainloop()

def wait():
    start = time.time()
    asyncio.run(sleep())
    print(f'Elapsed: {time.time() - start}')

async def sleep():
    await asyncio.sleep(1)

def main():
    wait()

main()
gui()
Driftwood answered 30/11, 2023 at 18:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.