SNIP IT: tk.Canvas Drag Items Around
Phlip
phlip_cpp at yahoo.com
Wed Jun 5 13:57:55 EDT 2002
phlip_cpp at yahoo.com (Phlip) wrote in message news:<63604d2.0206031518.2da29d3b at posting.google.com>...
> Hyp Ont:
>
> Many moons ago one Tom Vrankar posted a snippet to this forum
> regarding dragging Tkinter Canvas items around.
>
> I have upgraded it to actually move the target items. This also
> demonstrates canvasx and canvasy, the subject of recent mysteries.
>
> The snippet does not make allowances for the offset between the
> mouse point and the anchor point of the draggee; this should be
> easy to add. But the symptom is clicking an object and starting
> to drag makes it "snick" over to the mouse location.
This version of the snippet drags around polygons. These are trick
because one must update all the coords, not just the first one.
import sys, os, string, time, copy
import Tkinter
tk = Tkinter
# A Python example of drag and drop functionality within a single Tk
widget.
# The trick is in the bindings and event handler functions.
# Tom Vrankar twv at ici.net
# empirical events between dropee and target, as determined from Tk
8.0
# down.
# leave.
# up, leave, enter.
class CanvasDnD (tk.Frame):
def __init__ (self, master):
self.master =master
self.loc =self.dragged =0
tk.Frame.__init__ (self, master)
canvas =tk.Canvas (self, width =256, height =256,
relief =tk.RIDGE, background ="white", borderwidth =1)
self.defaultcolor =canvas.itemcget (canvas.create_text (30, 25,
text ="Item 1", tags ="DnD"), "fill")
canvas.create_text (175, 175, text ="Item 4", tags ="DnD")
canvas.create_text (225, 225, text ="Item 5", tags ="DnD")
x,y = 50, 200
canvas.create_polygon(x,y, [[x+0,y+0], [x+10,y+10], [x-10,y+10]],
fill='pink', tags = 'DnD')
x,y = 150, 40
canvas.create_polygon(x,y, [[x+0,y+0], [x+0,y+15], [x-15,y+10]],
fill='green', tags = 'DnD')
x,y = 120, 120
canvas.create_polygon(x,y, [[x+0,y+0], [x+15,y+0], [x+15,y+15],
[x+0,y+15]], fill='red', tags = 'DnD')
x,y = 120, 170
canvas.create_polygon(x,y, [[x+0,y+0], [x+15,y+0], [x+15,y+15],
[x+0,y+15]], fill='gray', tags = 'DnD')
canvas.pack (expand =1, fill =tk.BOTH)
canvas.tag_bind ("DnD", "<ButtonPress-1>", self.down)
canvas.tag_bind ("DnD", "<ButtonRelease-1>", self.chkup)
canvas.tag_bind ("DnD", "<Enter>", self.enter)
canvas.tag_bind ("DnD", "<Leave>", self.leave)
def down (self, event):
# print "Click on %s" %event.widget.itemcget (tk.CURRENT, "text")
# print "Click on %s" % event.widget.itemconfigure (tk.CURRENT)
print event.widget.coords(tk.CURRENT)
self.loc =1
self.dragged =0
event.widget.bind ("<Motion>", self.motion)
def motion (self, event):
root.config (cursor ="exchange")
cnv = event.widget
cnv.itemconfigure (tk.CURRENT, fill ="blue")
xy = cnv.canvasx(event.x), cnv.canvasy(event.y)
points = event.widget.coords (tk.CURRENT)
anchors = copy.copy(points[:2])
print points
for idx in range(len(points)):
# print idx, xy[idx % 2], anchors[idx % 2]
mouse = xy[idx % 2]
zone = anchors[idx % 2]
points[idx] = points[idx] - zone + mouse
print points
apply(event.widget.coords, [tk.CURRENT] + points)
def leave (self, event):
self.loc =0
def enter (self, event):
self.loc =1
if self.dragged == event.time:
self.up (event)
def chkup (self, event):
event.widget.unbind ("<Motion>")
root.config (cursor ="")
self.target =event.widget.find_withtag (tk.CURRENT)
event.widget.itemconfigure (tk.CURRENT, fill =self.defaultcolor)
if self.loc: # is button released in same widget as pressed?
self.up (event)
else:
self.dragged = event.time
def up (self, event):
event.widget.unbind ("<Motion>")
if (self.target ==event.widget.find_withtag (tk.CURRENT)):
print #"Select %s" %event.widget.itemcget (tk.CURRENT, "text")
else:
event.widget.itemconfigure (tk.CURRENT, fill ="blue")
self.master.update()
time.sleep (.1)
print "%s Drag-N-Dropped onto %s" \
%(event.widget.itemcget (self.target, "text"),
event.widget.itemcget (tk.CURRENT, "text"))
event.widget.itemconfigure (tk.CURRENT, fill =self.defaultcolor)
root =tk.Tk()
root.title ("Drag-N-Drop Demo")
CanvasDnD (root).pack()
root.mainloop()
--
Phlip
http://www.greencheese.org/MakeItSo
-- DARE to resist drug-war profiteering --
More information about the Python-list
mailing list