Python:将源小部件拖动到目标小部件上以更改其颜色

问题描述 投票:0回答:1

我正在研究 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”绑定中检测源小部件?最终我希望能够获取源按钮的颜色,并用它来设置目标按钮的颜色。

谢谢。

python tkinter drag-and-drop
1个回答
0
投票

我认为

'<<Drop>>'
仅在您使用模块tkinterdnd2时才存在。
此外,这个模块似乎只拖动外部文件和外部文本,但不拖动小部件。


您应该在

restore_position
中执行此操作 - 类似于答案中的代码

python - 如何创建拖放界面? - 堆栈溢出

问题是它在鼠标下提供顶部小部件 - 因此需要

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
© www.soinside.com 2019 - 2024. All rights reserved.