【发布时间】:2020-07-23 21:17:26
【问题描述】:
我在 tkinter 画布上有一张厨房桌子的图像。前景对象图像(例如,杯子)被插入到桌子图像的顶部。杯子图像具有 alpha 通道以删除其局部背景,因此杯子似乎坐在桌子上。背景图像和前景图像都使用以下标准方式添加到画布:
canvas.create_image()
上面描述的一切都有效。
目标是这样的:当鼠标悬停在杯子上时,在杯子图像周围放置一个圆圈(以便用户知道可以拾取物品)然后允许用户单击杯子图像并将其拖动到桌子上的新位置(即画布)。
我尝试将鼠标按下事件绑定到圆圈(参见下面的代码)。为此,我遵循下面链接的一般示例;但是,它在我的情况下不起作用。
python tkinter canvas when rectangle clicked
以下是重现问题的简化代码。代码将圆形放在画布上并定义了四个相关的回调。三是必绕;一个画布。期望是所有四个回调都应该工作。现实是通过 tags="click_zone" 绑定到圆圈的回调不起作用,而绑定到画布的回调起作用。
import cv2
from tkinter import Tk, Canvas
from PIL import ImageTk, Image
import time
class ClickZone:
def __init__(self, _canvas, _bbox):
self.click_zone = _canvas.create_oval(_bbox, tags=("click zone"))
_canvas.tag_bind("click zone", '<Enter>', self.on_enter)
_canvas.tag_bind("click zone", '<Leave>', self.on_leave)
_canvas.tag_bind("click zone", '<ButtonPress-1>', self.pick_up_object)
_canvas.bind("<ButtonRelease-1>", self.drop_object)
def drop_object(self, event):
print("Drop")
def pick_up_object(self, event):
print("Pick up")
def on_enter(self, event):
print("Enter")
def on_leave(self, event):
print("Leave")
root = Tk()
canvas = Canvas(root, width=800, height=600)
canvas.grid()
# Center of inserted object image
x_center_fg_object = 400
y_center_fg_object = 300
# Diameter of smallest circle fully enclosing inserted object image
fg_object_click_zone_radius = 250
# Bounding box around click zone circle
x0 = x_center_fg_object - fg_object_click_zone_radius
y0 = y_center_fg_object - fg_object_click_zone_radius
x1 = x_center_fg_object + fg_object_click_zone_radius
y1 = y_center_fg_object + fg_object_click_zone_radius
bbox = (x0, y0, x1, y1)
fg_object_click_zone = ClickZone(canvas, bbox)
root.mainloop()
最终,我想将拾取鼠标事件直接绑定到图像而不是圆圈;但是,我从未在网上找到有人成功将鼠标事件绑定到画布上的图像的示例。
【问题讨论】:
-
“从来没有在网上找到有人成功将鼠标事件绑定到画布上的图像的示例,所以......” - 令人惊讶的是,您以完全相同的方式绑定到图像您绑定到任何其他画布对象。
-
此答案适用于与椭圆形完全相同的图像:stackoverflow.com/a/6789351/7432
-
@Bryan Oakly -- 我可以使用您在上面链接的解决方案(谢谢),但我仍然想知道为什么我的代码不起作用。在这两种情况下,椭圆形和鼠标之间的绑定似乎相同,但链接代码有效,而我的代码无效。
-
我不知道。您的示例不会像发布的那样运行。
-
我发布了重现问题的代码。