SNIP IT: tk.Canvas Drag Items Around
Phlip
phlip_cpp at yahoo.com
Mon Jun 3 19:18:31 EDT 2002
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.
import sys, os, string, time
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,
font =("Helvetica", 14), text ="Item 1", tags ="DnD"), "fill")
canvas.create_text (75, 75,
font =("Helvetica", 14), text ="Item 2", tags ="DnD")
canvas.create_text (125, 125,
font =("Helvetica", 14), text ="Item 3", tags ="DnD")
canvas.create_text (175, 175,
font =("Helvetica", 14), text ="Item 4", tags ="DnD")
canvas.create_text (225, 225,
font =("Helvetica", 14), text ="Item 5", 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")
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")
x,y = cnv.canvasx(event.x), cnv.canvasy(event.y)
got = event.widget.coords (tk.CURRENT, x, y)
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/YaAw
-- I'l have my Web site call your Web site... --
More information about the Python-list
mailing list