Tkinter doesn't have any direct support for drag and drop within an application. However, drag and drop requires not much more than making suitable bindings for a button click (<ButtonPress-1>
), the mouse moving while the button is clicked (<B1-Motion>
), and when the button is released (<ButtonRelease-1>
).
Here is a very simplestic example which is designed to work with your code.
First, we'll create a class that can manage the dragging and dropping. It's easier to do this as a class rather than a collection of global functions.
class DragManager():
def add_dragable(self, widget):
widget.bind("<ButtonPress-1>", self.on_start)
widget.bind("<B1-Motion>", self.on_drag)
widget.bind("<ButtonRelease-1>", self.on_drop)
widget.configure(cursor="hand1")
def on_start(self, event):
# you could use this method to create a floating window
# that represents what is being dragged.
pass
def on_drag(self, event):
# you could use this method to move a floating window that
# represents what you're dragging
pass
def on_drop(self, event):
# find the widget under the cursor
x,y = event.widget.winfo_pointerxy()
target = event.widget.winfo_containing(x,y)
try:
target.configure(image=event.widget.cget("image"))
except:
pass
To use it, all you need to do is call the add_draggable
method, giving it the widget(s) you wish to drag.
For example:
label = Label(canvas, image=image)
...
dnd = DragManager()
dnd.add_dragable(label)
...
root.mainloop()
That's all it takes for the basic framework. It's up to you to create a floating draggable window, and to perhaps highlight the item(s) that can be dropped on.
Other implementations
For another implementation of the same concept, see https://github.com/python/cpython/blob/master/Lib/tkinter/dnd.py