Tkinterを使用してGUI開発ツール(46)を作成し、Tkinterのコントロールドラッグ機能を実現します。

Tkinterを使用してGUI開発ツールを作成する(46)Tkinterにコントロールのドラッグアンドドロップ機能を実装する
PythonはPython 3.8にアップグレードされており、Tkinterライブラリは引き続き独自のGUI開発ライブラリです。
ネイティブのtkinter.dndモジュールは、コントロールのドラッグのデモンストレーションを提供します。これは、さまざまなtkウィンドウでのコントロールのドラッグのデモンストレーションです。
dnd.pyファイルはC:\ Python \ Lib \ tkinterディレクトリにあり、元のファイルリーダーは自分で試すことができます。
ウィンドウのさまざまな領域でコントロールを移動するにはどうすればよいですか?
そこで、さらにtkinter.dndモジュールにカプセル化しましたこれにより、さまざまな領域またはさまざまなウィンドウでのコントロールのドラッグを実現できます。
HP_tk2のViewコントロールを使用して、ウィンドウを4つの領域に分割し、これらの4つの領域でデモンストレーションします。
以下にソースコードを直接示します。

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

プログラムの成果は以下のとおりです。
ここに画像の説明を挿入
読者は私の考えに従ってTkinterのドラッグアンドドロップ機能を改善することができます。

おすすめ

転載: blog.csdn.net/hepu8/article/details/108035629