Utilice Tkinter para crear herramientas de desarrollo de GUI (46) Implementar la función de control de arrastrar y soltar en Tkinter
Python se ha actualizado a Python 3.8, y la biblioteca Tkinter sigue siendo su propia biblioteca de desarrollo de GUI.
El módulo nativo tkinter.dnd proporciona una demostración del control de arrastre, que es una demostración de arrastre de controles en diferentes ventanas tk.
El archivo dnd.py se puede encontrar en el directorio C: \ Python \ Lib \ tkinter, y los lectores del archivo original pueden probarlo por sí mismos.
¿Cómo mover los controles en diferentes áreas de una ventana?
Entonces lo encapsulé aún más en el módulo tkinter.dnd, que puede realizar el arrastre de controles en diferentes áreas o diferentes ventanas.
Usamos el control de Vista de HP_tk2 para dividir la ventana en cuatro áreas y demostrar en estas cuatro áreas.
A continuación doy el código fuente directamente.
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()
Los resultados del programa son los siguientes.
Los lectores pueden mejorar la función de arrastrar y soltar de Tkinter de acuerdo con mis ideas.