1# Brownian motion -- an example of a NON multi-threaded Tkinter program ;) 2# By Michele Simoniato, inspired by brownian.py 3 4from Tkinter import * 5import random 6import sys 7 8WIDTH = 400 9HEIGHT = 300 10SIGMA = 10 11BUZZ = 2 12RADIUS = 2 13LAMBDA = 10 14FILL = 'red' 15 16stop = 0 # Set when main loop exits 17root = None # main window 18 19def particle(canvas): # particle = iterator over the moves 20 r = RADIUS 21 x = random.gauss(WIDTH/2.0, SIGMA) 22 y = random.gauss(HEIGHT/2.0, SIGMA) 23 p = canvas.create_oval(x-r, y-r, x+r, y+r, fill=FILL) 24 while not stop: 25 dx = random.gauss(0, BUZZ) 26 dy = random.gauss(0, BUZZ) 27 try: 28 canvas.move(p, dx, dy) 29 except TclError: 30 break 31 else: 32 yield None 33 34def move(particle): # move the particle at random time 35 particle.next() 36 dt = random.expovariate(LAMBDA) 37 root.after(int(dt*1000), move, particle) 38 39def main(): 40 global root, stop 41 root = Tk() 42 canvas = Canvas(root, width=WIDTH, height=HEIGHT) 43 canvas.pack(fill='both', expand=1) 44 np = 30 45 if sys.argv[1:]: 46 np = int(sys.argv[1]) 47 for i in range(np): # start the dance 48 move(particle(canvas)) 49 try: 50 root.mainloop() 51 finally: 52 stop = 1 53 54if __name__ == '__main__': 55 main() 56