1 """
2 Noticed this while reading wxpython-users maillist and found it too cool to not
3 make a tkinter version. This is a partial version of the original one found in
4 http://wiki.wxpython.org/BubblesToy
5 """
6
7 import Tkinter
8 import random
9 import math
10
11 class Bubble(object):
12 def __init__(self, canvas, x, y, death_size=25, color='green',
13 grow_speed=0.2):
14 self.x = x
15 self.y = y
16 self.radius = 5
17 self.death_size = death_size
18 self.grow_speed = grow_speed
19 self.canvas = canvas
20
21 self.bubble = self.canvas.create_oval(fill='white', outline=color,
22 width=2, *self._bubble_coords())
23
24 def _bubble_coords(self):
25 r = self.radius
26 return (self.x - r, self.y - r, self.x + r, self.y + r)
27
28 def go(self, to_remove):
29 if self.radius >= self.death_size:
30 to_remove.append(self)
31 self.canvas.delete(self.bubble)
32
33 def update_drawing(self, to_remove):
34 growth = math.log(self.radius) * self.grow_speed
35 self.radius += growth
36 self.canvas.coords(self.bubble, *self._bubble_coords())
37 self.go(to_remove)
38
39
40 class BubbleCanvas(Tkinter.Canvas):
41 def __init__(self, master, *args, **kwargs):
42 Tkinter.Canvas.__init__(self, master, *args, **kwargs)
43 self.bubbles = []
44 self.to_remove = []
45 self.last_pos = (-1, -1)
46
47 self.bind('<Motion>', self.on_motion)
48 self.bind('<ButtonRelease-1>', self.on_left_up)
49 self.bind('<ButtonRelease-3>', self.on_right_up)
50
51 def draw(self):
52 for bubble in self.bubbles:
53 bubble.update_drawing(self.to_remove)
54 while self.to_remove:
55 self.bubbles.remove(self.to_remove.pop())
56
57 def on_motion(self, event):
58 x, y = event.x, event.y
59 motion_score = abs(x - self.last_pos[0]) + abs(y - self.last_pos[1])
60 self.last_pos = (x, y)
61 if random.randint(0, motion_score) > 5:
62 self.bubbles.append(Bubble(self, x, y))
63 if random.randint(0, 100) == 0:
64 self.bubbles.append(Bubble(self, x, y, color='purple',
65 death_size=100, grow_speed=0.5))
66
67 def on_left_up(self, event):
68 self.bubbles.append(Bubble(self, event.x, event.y, color='yellow',
69 death_size=50, grow_speed=0.1))
70
71 def on_right_up(self, event):
72 self.bubbles.append(Bubble(self, event.x, event.y, color='blue',
73 death_size=80, grow_speed=0.6))
74
75
76 class BubbleFrame(Tkinter.Frame):
77 def __init__(self, title):
78 Tkinter.Frame.__init__(self)
79 self.master.title(title)
80
81 self.canvas = BubbleCanvas(self, background='white')
82 self.canvas.pack(expand=True, fill='both')
83 self.after(20, self.on_timer)
84
85 def on_timer(self):
86 self.canvas.draw()
87 self.after(20, self.on_timer)
88
89
90 root = Tkinter.Tk()
91 frame = BubbleFrame("Bubbles!")
92 frame.pack(expand=True, fill='both')
93 root.mainloop()
94