# Connecting Asyncio and Tkinter event loops?

**URL:** <https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722>\
**Category:** Ideas\
**Created:** [March 30, 2022, 5:38pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722 "2022-03-30T17:38:32Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![smontanaro](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/smontanaro/32/1389_2.png) [@smontanaro](https://discuss.python.org/u/smontanaro)\
**Post date:** [March 30, 2022, 5:38pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/1 "2022-03-30T17:38:32Z")

</div>

I recently resurrected a long dormant `tkinter` program. I was mildly  
surprised it still worked with no (or minimal) changes. It contained a  
commented out chunk of code which read “uncomment for Python 1.4”. 🙂  
I’m sure at some point I “ported” it to Python 3, but I don’t recall  
if or when that might have happened.

I’ve never used `asyncio`, but I got to wondering about better tracking  
of keyboard and mouse than my little program implements (it’s a  
computer activity monitor to force you to rest when needed). I thought  
about using `pynput`, which seems geared toward asyncio. That got me  
wondering if providing an async event handler function for tkinter  
makes sense. Given that both are in the stdlib, it seems like it might  
serve as a template for how it might work for other GUI libraries.

A quick check didn’t reveal anything, but did suggest questions about  
linking the `tkinter` and `asyncio` event loops do come up from  
time-to-time.

---

<div class="post-metadata">

**Author:** ![guido](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/guido/32/21_2.png) [@guido](https://discuss.python.org/u/guido)\
**Post date:** [March 30, 2022, 6:37pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/2 "2022-03-30T18:37:28Z")

</div>

Hi Skip! When asyncio was first introduced we did give some consideration to integrating it with UI event loops, but other than thinking “it should be possible” I am not aware of anyone actually creating such an integration. 🙂

---

<div class="post-metadata">

**Author:** ![smontanaro](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/smontanaro/32/1389_2.png) [@smontanaro](https://discuss.python.org/u/smontanaro)\
**Post date:** [March 30, 2022, 8:37pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/3 "2022-03-30T20:37:50Z")

</div>

Thanks, Guido. Would this be the right place to hammer out the details? I can’t see this requiring a PEP unless there are more than two opinions about were such a function belongs. I’ll see if I can create a hello world to start with.

---

<div class="post-metadata">

**Author:** ![guido](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/guido/32/21_2.png) [@guido](https://discuss.python.org/u/guido)\
**Post date:** [March 30, 2022, 9:31pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/4 "2022-03-30T21:31:33Z")

</div>

I would love it if you managed to get this working! Agreed that no PEP would be needed. Maybe the new APIs could be in a new submodule of the tkinter package?

---

<div class="post-metadata">

**Author:** ![blink1073](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/blink1073/32/2519_2.png) [@blink1073](https://discuss.python.org/u/blink1073)\
**Post date:** [March 30, 2022, 11:28pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/5 "2022-03-30T23:28:35Z")

</div>

We have some (somewhat hacky) asyncio/tk integration in ipykernel: [ipykernel/eventloops.py at fc51ba4cccbc3b56323f9fc75f0ba631916812d9 · ipython/ipykernel · GitHub](https://github.com/ipython/ipykernel/blob/fc51ba4cccbc3b56323f9fc75f0ba631916812d9/ipykernel/eventloops.py#L224)

---

<div class="post-metadata">

**Author:** ![smontanaro](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/smontanaro/32/1389_2.png) [@smontanaro](https://discuss.python.org/u/smontanaro)\
**Post date:** [March 31, 2022, 2:39pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/6 "2022-03-31T14:39:11Z")

</div>

I came up with the simplest thing I could get to work (warning: I have **never** used `asyncio` before), then extracted just an `AsyncTk` class. I’m sure it’s missing things a full-fledged asyncio-friendly Tk event loop would need.

> <https://gist.github.com/smontanaro/5e12c557602a76c609e46ca59387ad1c>

---

<div class="post-metadata">

**Author:** ![matmel](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/matmel/32/8118_2.png) [@matmel](https://discuss.python.org/u/matmel)\
**Post date:** [March 31, 2022, 2:54pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/7 "2022-03-31T14:54:09Z")

</div>

You might be interested the Trio “[guest mode](https://trio.readthedocs.io/en/stable/reference-lowlevel.html?highlight=GUI#using-guest-mode-to-run-trio-on-top-of-other-event-loops)” approach to the problem of interoperability of an async event loop and a GUI event loop.

I have no experience with it personally, just know that it exists. For what I understand it seems to work. And as asyncio will gain task groups in python 3.11 you may be able to reproduce that approach if you think it is worth it.

---

<div class="post-metadata">

**Author:** ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)\
**Post date:** [March 31, 2022, 4:16pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/8 "2022-03-31T16:16:00Z")

</div>

> [@guido](#):
>
> When asyncio was first introduced we did give some consideration to integrating it with UI event loops, but other than thinking “it should be possible” I am not aware of anyone actually creating such an integration. 🙂

FWIW, I used the Qt integration projects [quamash](https://pypi.org/project/Quamash/) and then [asyncqt](https://pypi.org/project/asyncqt/) for some light GUI work in the past and they felt pretty seamless. They’re unmaintained now, the current successor seems to be [qasync](https://github.com/CabbageDevelopment/qasync).  
So yes, it is possible. Thank y’all for thinking about it :‍)

---

<div class="post-metadata">

**Author:** ![congzhangzh](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/congzhangzh/32/24254_2.png) [@congzhangzh](https://discuss.python.org/u/congzhangzh)\
**Post date:** [November 30, 2024, 2:36am UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/9 "2024-11-30T02:36:29Z")

</div>

maybe we can follow electron’s way to make it work, which seems fit all the conditions!

> <https://github.com/electron/electron/blob/8f00cc9c0e78b95e4de14b9b9e1a7df20935e948/shell/common/node_bindings.cc#L929>

> <https://github.com/webview/webview_deno/issues/185>
>
> Hi Devs,
> 
> why disable "webview\_dispatch"?
> 
> Btw, I am the author of some im…plementation of webview like julia & python.
> 
> https://github.com/congzhangzh/webview\_python
> https://github.com/congzhangzh/Webview.jl
> 
> Tks,
> Cong

---

<div class="post-metadata">

**Author:** ![guido](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/guido/32/21_2.png) [@guido](https://discuss.python.org/u/guido)\
**Post date:** [November 30, 2024, 5:15am UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/10 "2024-11-30T05:15:15Z")

</div>

I can’t follow the code you quoted, but this has been a long-time wish for me. Can you write code to do it, or are you just suggesting we do it? Because this needs someone dedicated to follow through, and the existing asyncio devs just don’t have the time.

---

<div class="post-metadata">

**Author:** ![congzhangzh](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/congzhangzh/32/24254_2.png) [@congzhangzh](https://discuss.python.org/u/congzhangzh)\
**Post date:** [November 30, 2024, 6:44am UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/11 "2024-11-30T06:44:36Z")

</div>

sure, I’d like to make a demo project to test this idea! @guido

---

<div class="post-metadata">

**Author:** ![ssweber](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ssweber/32/9684_2.png) [@ssweber](https://discuss.python.org/u/ssweber)\
**Post date:** [November 30, 2024, 2:59pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/12 "2024-11-30T14:59:35Z")

</div>

This library looks promising:

[async-tkinter-loop](https://github.com/insolor/async-tkinter-loop)

---

<div class="post-metadata">

**Author:** ![brnsb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/brnsb/32/35944_2.png) [@brnsb](https://discuss.python.org/u/brnsb)\
**Post date:** [November 30, 2024, 7:05pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/13 "2024-11-30T19:05:58Z")

</div>

I need to look through my old projects, I had a very specific need for asynchronous tasks in Tkinter a couple of years back. By memory, I had a very similar approach to how they’ve handled it.

---

<div class="post-metadata">

**Author:** ![congzhangzh](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/congzhangzh/32/24254_2.png) [@congzhangzh](https://discuss.python.org/u/congzhangzh)\
**Post date:** [December 1, 2024, 11:40am UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/14 "2024-12-01T11:40:40Z")

</div>

First, need some help on libuv & python micro task process

I feel a simple PEP to guide the eventloop implement and gui message loop should works, and should works with all UI framework like QT/GTK/Win32/TK/Mac, some implement like pyside is very trick and too bad!

My prototype is work in progress, I make it work in some version, which use timely poll, which is bad!

I try to use semaphore to make a better one, it’s broken, should be fixable in the next step!

> <https://github.com/congzhangzh/python_gui_with_asyncio/blob/main/tk_with_asyncio_concept.py>

> **[GitHub - congzhangzh/uvloop: Ultra fast asyncio event loop.](https://github.com/congzhangzh/uvloop)**
>
> Ultra fast asyncio event loop.

Btw,

1. I use uvloop and Linux to test the idea
2. I fork uvloop and create a custom version
3. Integration to Ui loop should be easy, it seems all ui framework provides some utility to callback on ui thread, and support hook the message loop to do something at each loop,We need this to process microtask(loop’s ready queue)

---

<div class="post-metadata">

**Author:** ![graingert](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/graingert/32/26847_2.png) [@graingert](https://discuss.python.org/u/graingert)\
**Post date:** [December 3, 2024, 11:01am UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/16 "2024-12-03T11:01:10Z")

</div>

I’ve had some luck using trio guest mode and trio-asyncio

> <https://github.com/richardsheridan/trio-guest/blob/master/trio_guest_tkinter.py>

---

<div class="post-metadata">

**Author:** ![richardsheridan](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/richardsheridan/32/24352_2.png) [@richardsheridan](https://discuss.python.org/u/richardsheridan)\
**Post date:** [December 4, 2024, 4:17pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/17 "2024-12-04T16:17:34Z")

</div>

aioguest probably deserves to be mentioned in this thread as well.

> **[GitHub - oremanj/aioguest: Run asyncio and another event loop in the same...](https://github.com/oremanj/aioguest)**
>
> Run asyncio and another event loop in the same thread

---

<div class="post-metadata">

**Author:** ![guido](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/guido/32/21_2.png) [@guido](https://discuss.python.org/u/guido)\
**Post date:** [December 13, 2024, 12:06am UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/19 "2024-12-13T00:06:06Z")

</div>

Hi Cong Zhan,

I don’t see your post in the Discourse thread, and I also don’t see it as a Direct Message. So I’m not sure what happened. Maybe this reply appears on Discourse.

In any case, I recommend that you look into the Trio Guest Mode and aioguest (the same for asyncio), linked in the Discourse thread. I’m not sure I understand your code well enough to see what it does – do you have an explanation somewhere?

(I also recognize that you may have some trouble with English – alas, I have trouble with Chinese, and I’m not sure how to bridge that except via e.g. Google Translate or ChatGPT.)

---

<div class="post-metadata">

**Author:** ![davidism](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/davidism/32/3295_2.png) [@davidism](https://discuss.python.org/u/davidism)\
**Post date:** [December 13, 2024, 12:28am UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/20 "2024-12-13T00:28:08Z")

</div>

They deleted their reply.

---

<div class="post-metadata">

**Author:** ![mikeshardmind](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/mikeshardmind/32/14381_2.png) [@mikeshardmind](https://discuss.python.org/u/mikeshardmind)\
**Post date:** [December 13, 2024, 3:34pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/21 "2024-12-13T15:34:57Z")

</div>

I’m not sure how well connecting these would go from other experiences, it’s generally been best (In my experience anyhow) to use threading to run each needed event loop in it’s own thread, and keeping the UI event loop on the main thread, and put an asyncio event loop in a background thread, then communicate between them as needed.

I’ve been putting together a list of specific concurrency functionality within the standard library that if we could get stronger guarantees about safe usage that won’t be broken in the future could make this route more obvious and something that could be documented for use, possibly even with some repository template that has the skeleton of what’s needed already provided.

So far, the things that aren’t guaranteed but that have remained safe for years that would enable this:

- The safety of passing an `asyncio.Queue` between threads so long as methods of the queue are only used from the event loop it is bound to.
- The ability to create a `concurrent.futures.Future` not managed by an executor (This is specifically documented as something people should not do currently, but is safer than documentation suggests so long as only user of .set\_result is the creator of the Future)
- The ability to use `.set_result` on said futures without an executor (also documented as not to be done)

The `concurrent.futures.Future` bit is a little awkward since while users can recreate the functionality without using a Future, it then won’t work with things like `asyncio.wrap_future`, or `concurrent.futures.wait( ..., return_when="FIRST_COMPLETED")`

---

<div class="post-metadata">

**Author:** ![guido](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/guido/32/21_2.png) [@guido](https://discuss.python.org/u/guido)\
**Post date:** [December 13, 2024, 4:15pm UTC](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722/22 "2024-12-13T16:15:33Z")

</div>

> [@mikeshardmind](#):
>
> I’m not sure how well connecting these would go from other experiences, it’s generally been best (In my experience anyhow) to use threading to run each needed event loop in it’s own thread, and keeping the UI event loop on the main thread, and put an asyncio event loop in a background thread, then communicate between them as needed.

Did you look at the docs for Trio guest mode? The do this but improve on it by executing all user code (I.e., callbacks) on the main thread. That makes a lot of code simpler to port (apparently, I haven’t tried it).

[Next page](https://discuss.python.org/t/connecting-asyncio-and-tkinter-event-loops/14722.md?page=2)
