抑制其他 canvas 项对事件的反应

Suppressing other canvas items from reacting to event

我在 canvas 上有一个矩形监听事件,带有回调函数“A”。

canvas中的空白space也在监听带有回调函数“B”的事件。

当我右击矩形时,“A”和“B”都被执行。我明白为什么会这样(矩形在 canvas 上)。

我想要创建的行为是仅当我右键单击矩形时才执行“A”。 如何阻止空白 canvas 区域对事件做出反应?

请参阅下面的代码作为我当前行为的示例。

import tkinter as tk

window = tk.Tk()
window.geometry('500x500')
window.grid_rowconfigure(0, weight=1)
window.grid_columnconfigure(0, weight=1)

canvas = tk.Canvas(master=window)
canvas.grid(row=0, column=0, sticky='nsew')
canvas.bind('<Button-3>', lambda event: print('canvas right click'))

rectangle_id = canvas.create_rectangle(200, 200, 300, 300, fill='red')
canvas.tag_bind(rectangle_id, '<Button-3>', lambda event: print('rectangle right click'))

window.mainloop()

tkinter 中没有任何内置功能可以执行此操作。事实上,Canvas documentation 特意把这个叫出来:

If bindings have been created for a canvas window using the bind command, then they are invoked in addition to bindings created for the canvas's items using the bind widget command. The bindings for items will be invoked before any of the bindings for the window as a whole.

一个解决方法是让您的标签绑定设置某种标志来告诉 canvas 绑定不要做任何工作。

示例:

import tkinter as tk

do_right_click = True

def canvas_right_click(event):
    global do_right_click
    if do_right_click:
        print("canvas right click")
    do_right_click = True

def element_right_click(event):
    global do_right_click
    do_right_click = False  # prevent canvas from processing this event
    print("rectangle right click")

window = tk.Tk()
window.geometry('500x500')
window.grid_rowconfigure(0, weight=1)
window.grid_columnconfigure(0, weight=1)

canvas = tk.Canvas(master=window)
canvas.grid(row=0, column=0, sticky='nsew')
canvas.bind('<Button-3>', canvas_right_click)

rectangle_id = canvas.create_rectangle(200, 200, 300, 300, fill='red')
canvas.tag_bind(rectangle_id, '<Button-3>', element_right_click)

window.mainloop()