[issue27546] Integrate tkinter and asyncio (and async)

Terry J. Reedy report at bugs.python.org
Mon Jul 18 00:10:10 EDT 2016


New submission from Terry J. Reedy:

The last week of last February, there was a discussion of this topic on python-ideas as part of "How the heck does async/await work in Python 3.5".  I would like to re-start the discussion along with rescuing the two big chunks of code that were posted.

Guido, you said "it would be very useful to have an asyncio loop integrated with Tkinter".  Were you thinking of something added to either the asyncio or tkinter modules? What would be the minimum that you think would be worth adding?  What would a mininal test look like?

There are, of course, multiple strategies.  Maxime posted the code I copied into the attached tkselector.py.  No example usage was given.  I cannot run it on Windows because it uses a unix-only function.

Maxime, for us to use this, you need to sign the contributor agreement, which can be done via the net.  See https://www.python.org/psf/contrib/

As soon as I submit this, I will also upload my tkloop.py.  It defines a TkEventLoop class that adds root.update in the run_forever method.  It then uses the class for working example of a asyncio callback modifying a tk widget at times intervals.  As I note in the doc string, there is an issue with asyncio's _run_once() blocking forever.  I recently noticed that idlelib.run.main does something similar, running a loop that gets user input with 1/20 second timeout and calling tkapp.eval('update') whenever there is none.

Motivations:

1. Mix gui events (key, mouse, and others) with i/o events.

2. Use gui events with the new async syntax.  My simple example, in the callback typical of tkinter apps, has widgets, callback, and dynamics defined in different places.  I would like to be able to write the app in a more 'natural' style, using loops: something like

async def display_date(interval, end_time, loop=ai.get_event_loop()):
    label = tk.Label(root)
    label.pack()
    async for tick in timer(interval, end_time, loop):
         label['text'] = datetime.datetime.now()

Some python-tkinter beginners try to do something like this, except that for time delays they use while and time.sleep.  There have been many Stackoverflow questions about the resulting failures.  I would like to find out if 

I presume that converting my example to something like the above, using TkEventLoop, could be done easily enough by someone who knows how.

For only supporting tk events, it would be better to have a tkinter implementation of the needed subset of asyncio.events.AbstractEventLoop. The run and call methods are needed, the io methods not, but I am not sure where to draw the line in between.  The implementation of a few methods should be fairly easy: run_forever is mainloop, close is destroy; run_until_complete will be harder.

----------
files: tkselector.py
messages: 270688
nosy: Maxime S, gvanrossum, serhiy.storchaka, terry.reedy, yselivanov
priority: normal
severity: normal
stage: test needed
status: open
title: Integrate tkinter and asyncio (and async)
type: enhancement
versions: Python 3.6
Added file: http://bugs.python.org/file43769/tkselector.py

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue27546>
_______________________________________


More information about the Python-bugs-list mailing list