[Tkinter-discuss] Text drag&drop

Vasilis Vlachoudis Vasilis.Vlachoudis at cern.ch
Wed Oct 31 10:27:04 EDT 2018


Hi all,

moving from Canvas() to Text() I wanted to re-implement the same drag&drop
functionality I have.
I created a small test program show my problem(s).

I am creating two, Toplevel windows with MyText() inside.
The MyText extends the Text and adds a drag&drop.
For demonstration I've binded on the Control-Button-1 the starting of the drag action
it creates a "floating" Label() with the selected text, which is placed at the mouse position.
Now the problems:
1. The selection on the "drag" window keeps changing as I move the mouse.
   The selection is changing as if there was a grab_set() even if the cursor is on the second window.
2. If I drag the mouse on the second window, despite the Label is created() it doesn't show it.

How can I correct those problems?

Many thanks in advance
Vasilis


import tkinter as tk
import tkinter.dnd as Dnd

class MyText(tk.Text):
	def __init__(self, master, *kw, **kwargs):
		super().__init__(master, *kw, **kwargs)
		self.bind("<Control-Button-1>", self.button1)
		self.dnd_text = None

	# ----------------------------------------------------------------------
	def button1(self, event):
		Dnd.dnd_start(text1, event)
		self.dnd_text = text1.get(tk.SEL_FIRST, tk.SEL_LAST)

	# ----------------------------------------------------------------------
	def dnd_accept(self, source, event):
		return self

	# ----------------------------------------------------------------------
	def dnd_enter(self, source, event):
		self.focus_set()
		self.dnd_item = tk.Label(self, text=source.dnd_text,
					border=2, relief=tk.RAISED)
		self.dnd_motion(source, event)

	# ----------------------------------------------------------------------
	def dnd_leave(self, source, event):
		self.dnd_item.place_forget()
		self.dnd_item = None

	# ----------------------------------------------------------------------
	def dnd_motion(self, source, event):
		self.dnd_item.place(x=event.x, y=event.y)

	# ----------------------------------------------------------------------
	def dnd_end(self, target, event):
		if self.dnd_item:
			self.dnd_item.place_forget()
			self.dnd_item = None
		self.dnd_text = None

	# ----------------------------------------------------------------------
	# Object has been dropped here
	# ----------------------------------------------------------------------
	def dnd_commit(self, source, event):
		if self.dnd_item:
			self.dnd_item.place_forget()
			self.dnd_item = None
		if source.dnd_text is None: return

		self.insert(tk.CURRENT, source.dnd_text)
		self.dnd_text = None

root=tk.Tk()
root.title("Top1")
text1 = MyText(root)
text1.pack(fill=tk.BOTH, expand=tk.YES)
for i in range(1000):
	text1.insert(tk.END, "%d  The quick brown fox jumps over the lazy dog's tail\n"%(i))


top2  = tk.Toplevel(root)
top2.title("Top2")
text2 = MyText(top2)
text2.pack(fill=tk.BOTH, expand=tk.YES)


root.mainloop()


More information about the Tkinter-discuss mailing list