python – 拖放小部件tkinter

我正在尝试制作一个Python程序,您可以在其中移动小部件.

这是我的代码:

import tkinter as tk 
main = tk.Tk()
notesFrame = tk.Frame(main, bd = 4, bg = "a6a6a6")
notesFrame.place(x=10,y=10)
notes = tk.Text(notesFrame)
notes.pack()
notesFrame.bind("<B1-Motion>", lambda event: notesFrame.place(x = event.x, y = event.y)

但是,这会出现超级故障并且小部件来回跳跃.

谢谢!

最佳答案
您观察到的行为是由事件的坐标相对于拖动的窗口小部件引起的.用相对坐标更新小部件的位置(绝对坐标)显然会导致混乱.

为了解决这个问题,我使用了.winfo_x() and .winfo_y()函数(允许将相对坐标转换为绝对坐标),并使用Button-1事件来确定拖动开始时光标在窗口小部件上的位置.
以下是一个使窗口小部件可拖动的mixin.

class DragDropMixin:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.drag_start_x = 0
        self.drag_start_y = 0
        self.bind("<Button-1>", self.drag_start)
        self.bind("<B1-Motion>", self.drag_motion)

    def drag_start(self, event):
        self.drag_start_x = event.x
        self.drag_start_y = event.y

    def drag_motion(self, event):
        x = self.winfo_x() - self.drag_start_x + event.x
        y = self.winfo_y() - self.drag_start_y + event.y
        self.place(x=x, y=y)

用法:

# As always when it comes to mixins, make sure to
# inherit from DragDropMixin FIRST!
class DnDFrame(DragDropMixin, tk.Frame):
    pass

# This wouldn't work:
# class DnDFrame(tk.Frame, DragDropMixin):
#     pass

main = tk.Tk()
notesFrame = DnDFrame(main, bd=4, bg="grey")
notesFrame.place(x=10, y=10)
notes = tk.Text(notesFrame)
notes.pack()

转载注明原文:python – 拖放小部件tkinter - 代码日志