Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9a8cb84

Browse files
committed
Checked in some new Tk demos that I wrote a while ago.
1 parent 387c575 commit 9a8cb84

4 files changed

Lines changed: 1047 additions & 0 deletions

File tree

Demo/tkinter/guido/canvasevents.py

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
#! /usr/bin/env python
2+
3+
from Tkinter import *
4+
from Canvas import Oval, Group, CanvasText
5+
6+
7+
# Fix a bug in Canvas.Group as distributed in Python 1.4. The
8+
# distributed bind() method is broken. This is what should be used:
9+
10+
class Group(Group):
11+
def bind(self, sequence=None, command=None):
12+
return self.canvas.tag_bind(self.id, sequence, command)
13+
14+
class Object:
15+
16+
"""Base class for composite graphical objects.
17+
18+
Objects belong to a canvas, and can be moved around on the canvas.
19+
They also belong to at most one ``pile'' of objects, and can be
20+
transferred between piles (or removed from their pile).
21+
22+
Objects have a canonical ``x, y'' position which is moved when the
23+
object is moved. Where the object is relative to this position
24+
depends on the object; for simple objects, it may be their center.
25+
26+
Objects have mouse sensitivity. They can be clicked, dragged and
27+
double-clicked. The behavior may actually determined by the pile
28+
they are in.
29+
30+
All instance attributes are public since the derived class may
31+
need them.
32+
33+
"""
34+
35+
def __init__(self, canvas, x=0, y=0, fill='red', text='object'):
36+
self.canvas = canvas
37+
self.x = x
38+
self.y = y
39+
self.pile = None
40+
self.group = Group(self.canvas)
41+
self.createitems(fill, text)
42+
43+
def __str__(self):
44+
return str(self.group)
45+
46+
def createitems(self, fill, text):
47+
self.__oval = Oval(self.canvas,
48+
self.x-20, self.y-10, self.x+20, self.y+10,
49+
fill=fill, width=3)
50+
self.group.addtag_withtag(self.__oval)
51+
self.__text = CanvasText(self.canvas,
52+
self.x, self.y, text=text)
53+
self.group.addtag_withtag(self.__text)
54+
55+
def moveby(self, dx, dy):
56+
if dx == dy == 0:
57+
return
58+
self.group.move(dx, dy)
59+
self.x = self.x + dx
60+
self.y = self.y + dy
61+
62+
def moveto(self, x, y):
63+
self.moveby(x - self.x, y - self.y)
64+
65+
def transfer(self, pile):
66+
if self.pile:
67+
self.pile.delete(self)
68+
self.pile = None
69+
self.pile = pile
70+
if self.pile:
71+
self.pile.add(self)
72+
73+
def tkraise(self):
74+
self.group.tkraise()
75+
76+
77+
class Bottom(Object):
78+
79+
"""An object to serve as the bottom of a pile."""
80+
81+
def createitems(self, *args):
82+
self.__oval = Oval(self.canvas,
83+
self.x-20, self.y-10, self.x+20, self.y+10,
84+
fill='gray', outline='')
85+
self.group.addtag_withtag(self.__oval)
86+
87+
88+
class Pile:
89+
90+
"""A group of graphical objects."""
91+
92+
def __init__(self, canvas, x, y, tag=None):
93+
self.canvas = canvas
94+
self.x = x
95+
self.y = y
96+
self.objects = []
97+
self.bottom = Bottom(self.canvas, self.x, self.y)
98+
self.group = Group(self.canvas, tag=tag)
99+
self.group.addtag_withtag(self.bottom.group)
100+
self.bindhandlers()
101+
102+
def bindhandlers(self):
103+
self.group.bind('<1>', self.clickhandler)
104+
self.group.bind('<Double-1>', self.doubleclickhandler)
105+
106+
def add(self, object):
107+
self.objects.append(object)
108+
self.group.addtag_withtag(object.group)
109+
self.position(object)
110+
111+
def delete(self, object):
112+
object.group.dtag(self.group)
113+
self.objects.remove(object)
114+
115+
def position(self, object):
116+
object.tkraise()
117+
i = self.objects.index(object)
118+
object.moveto(self.x + i*4, self.y + i*8)
119+
120+
def clickhandler(self, event):
121+
pass
122+
123+
def doubleclickhandler(self, event):
124+
pass
125+
126+
127+
class MovingPile(Pile):
128+
129+
def bindhandlers(self):
130+
Pile.bindhandlers(self)
131+
self.group.bind('<B1-Motion>', self.motionhandler)
132+
self.group.bind('<ButtonRelease-1>', self.releasehandler)
133+
134+
movethis = None
135+
136+
def clickhandler(self, event):
137+
tags = self.canvas.gettags('current')
138+
for i in range(len(self.objects)):
139+
o = self.objects[i]
140+
if o.group.tag in tags:
141+
break
142+
else:
143+
self.movethis = None
144+
return
145+
self.movethis = self.objects[i:]
146+
for o in self.movethis:
147+
o.tkraise()
148+
self.lastx = event.x
149+
self.lasty = event.y
150+
151+
doubleclickhandler = clickhandler
152+
153+
def motionhandler(self, event):
154+
if not self.movethis:
155+
return
156+
dx = event.x - self.lastx
157+
dy = event.y - self.lasty
158+
self.lastx = event.x
159+
self.lasty = event.y
160+
for o in self.movethis:
161+
o.moveby(dx, dy)
162+
163+
def releasehandler(self, event):
164+
objects = self.movethis
165+
if not objects:
166+
return
167+
self.movethis = None
168+
self.finishmove(objects)
169+
170+
def finishmove(self, objects):
171+
for o in objects:
172+
self.position(o)
173+
174+
175+
class Pile1(MovingPile):
176+
177+
x = 50
178+
y = 50
179+
tag = 'p1'
180+
181+
def __init__(self, demo):
182+
self.demo = demo
183+
MovingPile.__init__(self, self.demo.canvas, self.x, self.y, self.tag)
184+
185+
def doubleclickhandler(self, event):
186+
try:
187+
o = self.objects[-1]
188+
except IndexError:
189+
return
190+
o.transfer(self.other())
191+
MovingPile.doubleclickhandler(self, event)
192+
193+
def other(self):
194+
return self.demo.p2
195+
196+
def finishmove(self, objects):
197+
o = objects[0]
198+
p = self.other()
199+
x, y = o.x, o.y
200+
if (x-p.x)**2 + (y-p.y)**2 < (x-self.x)**2 + (y-self.y)**2:
201+
for o in objects:
202+
o.transfer(p)
203+
else:
204+
MovingPile.finishmove(self, objects)
205+
206+
class Pile2(Pile1):
207+
208+
x = 150
209+
y = 50
210+
tag = 'p2'
211+
212+
def other(self):
213+
return self.demo.p1
214+
215+
216+
class Demo:
217+
218+
def __init__(self, master):
219+
self.master = master
220+
self.canvas = Canvas(master,
221+
width=200, height=200,
222+
background='yellow',
223+
relief=SUNKEN, borderwidth=2)
224+
self.canvas.pack(expand=1, fill=BOTH)
225+
self.p1 = Pile1(self)
226+
self.p2 = Pile2(self)
227+
o1 = Object(self.canvas, fill='red', text='o1')
228+
o2 = Object(self.canvas, fill='green', text='o2')
229+
o3 = Object(self.canvas, fill='light blue', text='o3')
230+
o1.transfer(self.p1)
231+
o2.transfer(self.p1)
232+
o3.transfer(self.p2)
233+
234+
235+
# Main function, run when invoked as a stand-alone Python program.
236+
237+
def main():
238+
root = Tk()
239+
demo = Demo(root)
240+
root.protocol('WM_DELETE_WINDOW', root.quit)
241+
root.mainloop()
242+
243+
if __name__ == '__main__':
244+
main()
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#! /usr/bin/env python
2+
3+
"""Play with the new Tk 8.0 toplevel menu option."""
4+
5+
from Tkinter import *
6+
7+
class App:
8+
9+
def __init__(self, master):
10+
self.master = master
11+
12+
self.menubar = Menu(self.master)
13+
14+
self.filemenu = Menu(self.menubar)
15+
16+
self.filemenu.add_command(label="New")
17+
self.filemenu.add_command(label="Open...")
18+
self.filemenu.add_command(label="Close")
19+
self.filemenu.add_separator()
20+
self.filemenu.add_command(label="Quit", command=self.master.quit)
21+
22+
self.editmenu = Menu(self.menubar)
23+
24+
self.editmenu.add_command(label="Cut")
25+
self.editmenu.add_command(label="Copy")
26+
self.editmenu.add_command(label="Paste")
27+
28+
self.menubar.add_cascade(label="File", menu=self.filemenu)
29+
self.menubar.add_cascade(label="Edit", menu=self.editmenu)
30+
31+
self.top = Toplevel(menu=self.menubar)
32+
33+
# Rest of app goes here...
34+
35+
def main():
36+
root = Tk()
37+
root.withdraw()
38+
app = App(root)
39+
root.mainloop()
40+
41+
if __name__ == '__main__':
42+
main()

0 commit comments

Comments
 (0)