Hi all,

answering to my own email :)

#2. I found out my mistake why the Label doesn't appear on the second window
the "event" that it is passed to the dnd_motion is the event referring to the 
original
window and not the target one. So instead of using the event.x, event.y
I need to use the root coordinates and I convert them to local ones
                x = event.x_root - self.winfo_rootx()
                y = event.y_root - self.winfo_rooty()
                self.dnd_item.place(x=x, y=y)

#1. However I cannot get rid of the #1. I've tried to subclass the DndHandler()
especially the on_motion() method to delete the text anchor (dirty hack) after
looking at the text.tcl  as well deleting the selection and calling the 
CancelRepeat
to avoid the auto-scrolling, but nothing worked ok.
Is there a way to tell the Text() to stop the selection?

class MyDndHandler(Dnd.DndHandler):
        def __init__(self, source, event):
                super().__init__(source, event)
                anchor = self.source.tk.call("tk::TextAnchor", self.source._w)
                self.source.mark_unset(anchor)

        def on_motion(self, event):
                super().on_motion(event)
                anchor = self.source.tk.call("tk::TextAnchor", self.source._w)
                self.source.mark_unset(anchor)
#               if self.target is not self.source: 
self.source.tk.call("tk::CancelRepeat")
#               self.source.tag_remove(tk.SEL, "1.0", tk.END)
                return "break"

def dnd_start(source, event):
        h = MyDndHandler(source, event)
        if h.root:
                return h
        else:
                return None

Vasilis 


________________________________________
From: Tkinter-discuss 
[tkinter-discuss-bounces+vasilis.vlachoudis=cern...@python.org] on behalf of 
Vasilis Vlachoudis [vasilis.vlachou...@cern.ch]
Sent: Wednesday, October 31, 2018 15:27
To: tkinter-discuss@python.org
Subject: [Tkinter-discuss] Text drag&drop

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()
_______________________________________________
Tkinter-discuss mailing list
Tkinter-discuss@python.org
https://mail.python.org/mailman/listinfo/tkinter-discuss
_______________________________________________
Tkinter-discuss mailing list
Tkinter-discuss@python.org
https://mail.python.org/mailman/listinfo/tkinter-discuss

Reply via email to