Terry J. Reedy added the comment:

Guido, that seems like a reasonable roadmap.  The examples directory is not in 
the CPython repo, but I found it here.
https://github.com/python/asyncio/tree/master/examples

For a demo based on crawl.py, the goal would be a live status report.  Perhaps 
as files are fetched, they could be entered into a Treeview-based url tree, 
with columns for the statistics. (I still have to learn to practical use of 
Treeview.)  This would require adding widget data insertion commands within the 
crawl code.  Who actually wrote it, that would understand it?

Responsiveness should be a matter of prioritizing events.  Using the  asyncio 
loop as a base, I did the minimum needed for the first demo and for the initial 
part of the follow-up below.  For general use, _run_once should be modified to 
always let gui events be handled 'soon' by either not blocking or having a 
short timeout.  The root.update call could be moved from run_forever to 
multiple places within _run_once.  At an extreme, the _process_events 
implementations could be modified to call root.update() after processing each 
io event.  According to timeit.timeit(root.update), a do-nothing call takes 
less than 4 microseconds on my machine.

---

I implemented my idea of updating a tk widget in an async for loop.  The 
attached tkaloop does so, with the syntax I proposed previously.  There is only 
a change to the timer api.  With respect to the datetime clock, the behavior is 
essentially the same as with the first code.

Given that one can do the same thing with a normal for loop and explicit update 
(as some beginners try to do), is this useful?

1. Responsiveness: A normal for-loop blocks, freezing the gui.  To test that 
this is not so here, I added a button to do something visible - change a 
background color.  While the clock is running, it only sort-of works, because 
clicks are only processed after each 1 second tick.  The reason is that the 
select call in _run_once gets a timeout that is the minimum time to a scheduled 
event.  (The same should be true in tkloop.py if similarly modified.)  The next 
step is to modify _run_once as discussed above.

Tk allows one to specify delays to the nearest millisecond and on my machine, 
that precision is real.

from tkinter import *
import time
        
root = Tk()
root.withdraw()
timer = time.perf_counter
##n = 999
##delay = 1
n=1
delay=337
def tick():
    global n
    if n:
        n -= 1
        root.after(delay, tick)
    else:
        print(timer() - start)

tick()
start = timer()
root.mainloop()

prints .3370... in multiple runs. 1000 loops with a delay of 1 ms takes 1.05... 
seconds.  Similar performance would be a target for run_forever.

2. Parallel looping.  Supposed we wanted to automate the background color 
changes, with an interval of, say x seconds.  If x is, say, .3, then one could 
use .1 second ticks and an update block that flips the background every 3 ticks 
and the clock every 10.

But what if the intervals are not so conveniently commensurable or the separate 
updates not so easily mashed together into one loop block?
Parallel looping with chained callbacks, whether with tk or asyncio is fairly 
easy.  I presume it could be done with asyncio coroutines (but have no 
experience).  What I would like, but cannot see, is a way to do so with async 
for.  Within a function, async for blocks execution of remaining code after the 
for statement the same as normal for statement.

My conclusion thus far: with the response issue solved, a single async for loop 
could work for some time-driven applications, including some that beginners 
write, but not all.

An alternative for reducing the callback boilerplate is an animate function.  I 
have thought of writing one for tkinter, but have not yet because I have not 
yet needed one for IDLE.

----------
Added file: http://bugs.python.org/file43802/tkaloop.py

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue27546>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to