Use Tkinter to create GUI development tools (46) to realize the control drag function in Tkinter

Use Tkinter to create GUI development tools (46) Implement control drag and drop function in Tkinter
Python has been upgraded to Python 3.8, and the Tkinter library is still its own GUI development library.
The native tkinter.dnd module provides a demonstration of control dragging. This is a demonstration of dragging controls in different tk windows.
The dnd.py file can be found in the C:\Python\Lib\tkinter directory, and the original file readers can try it by themselves.
How to move the controls in different areas of a window?
So I further encapsulated it in the tkinter.dnd module, which can realize dragging of controls in different areas or windows.
We use the View control of HP_tk2 to divide the window into four areas, and demonstrate in these four areas.
Below I give the source code directly.

import  tkinter  as  tk   #导入Tkinter
import tkinter.dnd as dnd
import HP_tk2 as htk
#独狼荷蒲qq:2886002
#通通小白python量化群:524949939
#微信公众号:独狼股票分析
class  dndIcon:
    def __init__(self, idname = None):
        self.idname = idname
        self.canvas = None
        self.label = None
        self.id = None

    def attach(self, canvas, x=10, y=10):
        if canvas is self.canvas:
            self.canvas.coords(self.id, x, y)
            return
        if self.canvas:
            self.detach()
        if not canvas:
            return
        id = canvas.create_window(x, y, window=self.idname, anchor="nw")
        self.canvas = canvas
        self.id = id
        self.idname.bind("<ButtonPress>", self.press)

    def detach(self):
        canvas = self.canvas
        if not canvas:
            return
        id = self.id
        label = self.label
        self.canvas = self.label = self.id = None
        canvas.delete(id)
        self.idname.place_forget()

    def press(self, event):
        if dnd.dnd_start(self, event):
            # where the pointer is relative to the label widget:
            self.x_off = event.x
            self.y_off = event.y
            # where the widget is relative to the canvas:
            self.x_orig, self.y_orig = self.canvas.coords(self.id)

    def move(self, event):
        x, y = self.where(self.canvas, event)
        self.canvas.coords(self.id, x, y)

    def putback(self):
        self.canvas.coords(self.id, self.x_orig, self.y_orig)

    def where(self, canvas, event):
        # where the corner of the canvas is relative to the screen:
        x_org = canvas.winfo_rootx()
        y_org = canvas.winfo_rooty()
        # where the pointer is relative to the canvas widget:
        x = event.x_root - x_org
        y = event.y_root - y_org
        # compensate for initial pointer offset
        return x - self.x_off, y - self.y_off

    def dnd_end(self, target, event):
        pass


#可拖拽控件的控件
class dndwidget(tk.Frame):
    def __init__(self, master,**kw):
        tk.Frame.__init__(self, master,**kw)  
        self.top = master
        self.canvas = tk.Canvas(self.top, width=100, height=100,**kw)
        self.canvas.pack(fill="both", expand=1)
        self.canvas.dnd_accept = self.dnd_accept

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

    def dnd_enter(self, source, event):
        self.canvas.focus_set() # Show highlight border
        x, y = source.where(self.canvas, event)
        x1, y1, x2, y2 = source.canvas.bbox(source.id)
        dx, dy = x2-x1, y2-y1
        self.dndid = self.canvas.create_rectangle(x, y, x+dx, y+dy)
        self.dnd_motion(source, event)

    def dnd_motion(self, source, event):
        x, y = source.where(self.canvas, event)
        x1, y1, x2, y2 = self.canvas.bbox(self.dndid)
        self.canvas.move(self.dndid, x-x1, y-y1)

    def dnd_leave(self, source, event):
        self.top.focus_set() # Hide highlight border
        self.canvas.delete(self.dndid)
        self.dndid = None

    def dnd_commit(self, source, event):
        self.dnd_leave(source, event)
        x, y = source.where(self.canvas, event)
        source.attach(self.canvas, x, y)
          



def test2():
    root = tk.Tk()
    root.geometry('{}x{}+{}+{}'.format(800,600, 250, 350)) #改变窗口位置和大小
    root.title('dnd拖拽演示')
    v=htk.View(root,kind='田')
    v.pack()
    t1 = dndwidget(v.v[0])
    t2 = dndwidget(v.v[1],bg='green')
    t3 = dndwidget(v.v[2],bg='yellow')
    t4 = dndwidget(v.v[3],bg='blue')
    
    i1 = dnd.Icon("ICON1")
    i2 = dnd.Icon("ICON2")
    i3 = dnd.Icon("ICON3")
    bt=tk.Button(v.v[3], text="Quit")
    i4 = dndIcon(bt)
    
    i1.attach(t1.canvas)
    i2.attach(t2.canvas)
    i3.attach(t3.canvas)    
    i4.attach(t4.canvas)    
    root.mainloop()
    

if __name__ == '__main__':
    test2()

The results of the program are as follows.
Insert picture description here
Readers can improve Tkinter's drag-and-drop function according to my ideas.

Guess you like

Origin blog.csdn.net/hepu8/article/details/108035629