【问题标题】:How to click and drag image already inserted on top of another image on tkinter canvas如何单击并拖动已插入 tkinter 画布上另一个图像顶部的图像
【发布时间】: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 -- 我可以使用您在上面链接的解决方案(谢谢),但我仍然想知道为什么我的代码不起作用。在这两种情况下,椭圆形和鼠标之间的绑定似乎相同,但链接代码有效,而我的代码无效。
  • 我不知道。您的示例不会像发布的那样运行。
  • 我发布了重现问题的代码。

标签: python tkinter canvas


【解决方案1】:

至少部分问题是因为您使用tags="click zone"。标签应该是列表或元组,而不是字符串。由于 tcl 解释空格的方式,底层 tcl/tk 画布认为您正在应用两个标签:“click”和“zone”。因此,您对“点击区域”的绑定将不起作用。

另一个问题是画布对象绑定仅适用于对象本身。对于一个圆圈,这意味着 &lt;ButtonPress-1&gt; 仅在您单击圆圈的轮廓时有效,而不是在您单击圆圈内部时有效。如果您添加填充颜色,您将能够单击圆圈上的任意位置。

至于绑定到图像,其工作方式与绑定到任何其他画布对象完全相同。这个关于拖放的类似问题的答案有一个完整的工作解决方案:https://stackoverflow.com/a/6789351/7432

【讨论】:

  • 谢谢,您的回答解决了全部问题。关于单击轮廓与单击内部圆圈的一点点对我来说特别有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-07
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多