tkinter listbox drag and drop tkinter listbox drag and drop tkinter tkinter

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"))