tkinter listbox drag and drop
The key to drag and drop boils down to needing to do three things:
- bind on
<ButtonPress-1>
to select the item to be dragged - bind on
<B1-Motion>
to do the drag - bind on
<ButtonRelease-1>
to do the drop
None of this requires any subclassing. All of these bindings are on the listbox widget. You'll probably want to create an instance of Toplevel
with a text label in it and the window decorations removed (using wm_overrideredirect(True)
) to represent the item being dragged.
On the drop, you'll need to convert the coordinates of the mouse to canvas coordinates using the canvasx
and canvasy
methods of the canvas. Instead of starting with event.x
and event.y
(which are relative to the listbox), use the winfo_pointerxy
method to get the screen coordinates of the mouse, then do a little math.
Here's an example of how you could do the drop:
def _on_drag_drop(self, event): i = self.listbox.curselection()[0] text = self.listbox.get(i) wx, wy = self.canvas.winfo_rootx(), self.canvas.winfo_rooty() x,y = self.winfo_pointerxy() cx = self.canvas.canvasx(x-wx) cy = self.canvas.canvasy(y-wy) self.canvas.create_text(cx,cy,text=text, anchor="sw") self.canvas.configure(scrollregion=self.canvas.bbox("all"))