Drawing in "Slow motion".
Scott David Daniels
daniels at DevelopNET.com
Tue Feb 12 15:21:52 EST 2002
Eric Brunel <eric.brunel at pragmadev.com> wrote in message news:<a4ba6i$14bg$1 at norfair.nerim.net>...
> Hans Kristian Ruud wrote:
> > ...(The actual drawing procedure is triggered by an event bound to a
> > Button).
> > My problem is that I would like the program to draw one line at a time;
> > then pause, then draw the next line... and so on....
> Two solutions come to my mind:
> - keep your time.sleep calls, but call the update_idletasks method on the
> canvas after each sleep. The call should redraw the screen.
> - a bit trickier: use the delayed callback facility in Tk via the "after"
> method to draw while your application is running...
Here is a solution that requires less "program inversion" on your
actual drawing. The "yield" of the drawing generator is used to do
the inversion. Obviously, 2.2 is required. Code shamelessly stolen
from Eric Brunel's fine example.
from __future__ import generators
import random
from Tkinter import *
w, h = 500, 500
root = Tk()
cnv = Canvas(root, width=w, height=h)
cnv.pack(side=TOP)
def draw(count):
"""A generator that draws with a 'yield' at each time point."""
x, y = random.randrange(w), random.randrange(h)
for i in range(count):
oldx, oldy = x, y
x, y = random.randrange(w), random.randrange(h)
cnv.create_line(oldx, oldy, x, y)
yield None
# Put in a button to walk through the drawing
Button(root, text='Click', command=draws(10).next).pack(side=TOP)
# Put in a button to do a "timed" walk through the drawing
def per_tick():
"""This gets executed once per 'tick' to do the drawing"""
try:
draw_step()
root.after(500, per_tick)
except StopIteration:
pass
def timed():
"Once per button push: set up the generator for per_tick, and start it."""
global draw_step
draw_step = draw(17).next
root.after(500, per_tick)
Button(root, text='Timed', command=timed).pack(side=TOP)
daniels at DevelopNET.com
More information about the Python-list
mailing list