我正在研究 Tkinter 中的 Python 拖放功能。我这样做是为了对我正在做的事情进行概念验证。然而,它并没有完全按预期工作。我创建了两个按钮(一个红色,一个蓝色),其想法是,当我将其中一个按钮拖放到另一个按钮上时,颜色应更改为青色。然而这不起作用。我的代码在这里:
from tkinter import *
# import tkinterdnd2 as tkd
widget_x_restore = 0
widget_y_restore = 0
def drag_start(event):
widget = event.widget
global widget_x_restore
global widget_y_restore
widget_x_restore = widget.winfo_x()
widget_y_restore = widget.winfo_y()
widget.startX = event.x
widget.startY = event.y
widget.lift()
def drag_motion(event):
widget = event.widget
x = widget.winfo_x() - widget.startX + event.x
y = widget.winfo_y() - widget.startY + event.y
widget.place(x=x, y=y)
def restore_position(event):
widget = event.widget
print(widget)
widget.place(x=widget_x_restore, y=widget_y_restore)
def drop(event):
target_button = event.widget # Access the target button
if isinstance(target_button, Button):
target_button.config(bg="cyan", fg="cyan") # Change target button color
root = Tk()
root.geometry("600x400+200+100")
button1 = Button(root, text="button1", bg="red", fg="red", width=10, height=5)
button1.place(x=10, y=100)
button2 = Button(root, text="button2", bg="blue", fg="blue", width=10, height=5)
button2.place(x=200, y=200)
button1.bind("<Button-1>", drag_start)
button1.bind("<B1-Motion>", drag_motion)
button1.bind("<ButtonRelease-1>", restore_position)
button1.bind('<<Drop>>', drop)
button2.bind("<Button-1>", drag_start)
button2.bind("<B1-Motion>", drag_motion)
button2.bind("<ButtonRelease-1>", restore_position)
button2.bind('<<Drop>>', drop)
root.mainloop()
没有颜色变化。所以第一个问题是,我做错了什么?
更新:将 drop() 函数更改为:
def drop(event):
target_button = event.widget # Access the target button
print(f'>>>> {target_button}')
if isinstance(target_button, Button):
target_button.config(bg="cyan", fg="cyan") # Change target button color
回调好像没有执行?我从 print 语句中得到零输出。
第二个问题是,是否可以从“drop”绑定中检测源小部件?最终我希望能够获取源按钮的颜色,并用它来设置目标按钮的颜色。
谢谢。
我认为
'<<Drop>>'
仅在您使用模块tkinterdnd2时才存在。您应该在
restore_position
中执行此操作 - 类似于答案中的代码
问题是它在鼠标下提供顶部小部件 - 因此需要
update()
将源小部件移动到旧位置,然后目标小部件是鼠标下的顶部小部件。
def restore_position(event):
widget = event.widget
print('source:', widget)
widget.place(x=widget_x_restore, y=widget_y_restore)
root.update_idletasks() # move top widget (source widget), to access widget below (target widget)
x,y = event.widget.winfo_pointerxy()
target = event.widget.winfo_containing(x,y)
print('target:', target)
if isinstance(target, tk.Button):
target.config(bg="cyan", fg="cyan") # Change target button color