如何在 Python Tkinter 中停止事件传播?


Tkinter 事件在处理小部件的不同对象和属性以及应用程序的元素方面非常强大。例如鼠标事件和键盘按钮事件,可以通过将事件或回调函数绑定到按钮来处理。

假设我们正在创建一个应用程序,该应用程序具有两个在画布小部件中定义的对象的单击事件。这两个对象基本上是在画布内定义的形状(矩形和椭圆)。

我们可以执行诸如按钮单击事件之类的操作来验证用户是否单击了矩形或椭圆。要执行此操作,我们可以使用 **tag_bind(shape, "Button", callback)** 函数,该函数在按钮单击特定形状时触发回调事件。

示例

以下示例演示了此应用程序的工作原理。在这里,我们创建了两个函数,当用户单击特定形状时,这些函数将打印信息。

# Import the required libraries
from tkinter import *

# Create an instance of tkinter frame or window
win = Tk()

# Set the size of the window
win.geometry("700x350")

def oval_mouse_click(event):
   event.widget.tag_click = True
   print("You have clicked the oval")

def rec_mouse_click(event):
   event.widget.tag_click=True
   print("You have clicked the rectangle")

def canvas_click(event):
   if event.widget.tag_click:
      event.widget.tag_click = False
      return

# Create a canvas widget
canvas = Canvas(win)

# Create an oval inside the canvas
oval = canvas.create_oval(500 / 2 - 10, 400 / 2 - 10, 500 / 2 + 10, 400 / 2 + 10, fill='red')

# Create a rectangle inside the canvas
rectangle = canvas.create_rectangle(50, 0, 100, 50, fill='blue')

canvas.tag_bind(oval, "<Button-1>", oval_mouse_click)
canvas.tag_bind(rectangle, "<Button-1>", rec_mouse_click)
canvas.bind("<Button-1>", canvas_click)
canvas.pack()

win.mainloop()

输出

运行以上代码将显示一个带有两个形状(矩形和椭圆)的窗口。单击每个形状将在主屏幕上打印消息,验证发生了哪个事件。

单击圆形时,您将收到以下响应:

You have clicked the oval

单击矩形时,您将收到以下响应:

You have clicked the rectangle

但是,单击画布时,您将不会收到任何响应,因为我们已设置 **"event.widget.tag_click = False"**。

示例

现在,让我们在所有三个函数中注释掉 **event.widget.tag_click** 部分。代码如下所示:

# Import the required libraries
from tkinter import *

# Create an instance of tkinter frame or window
win = Tk()

# Set the size of the window
win.geometry("700x350")

def oval_mouse_click(event):
   # event.widget.tag_click = True
   print("You have clicked the oval")

def rec_mouse_click(event):
   # event.widget.tag_click=True
   print("You have clicked the rectangle")

def canvas_click(event):
   # if event.widget.tag_click:
   #    event.widget.tag_click = False
   #    return
   print ("You have clicked the Canvas")

# Create a canvas widget
canvas = Canvas(win)

# Create an oval inside the canvas
oval = canvas.create_oval(500 / 2 - 10, 400 / 2 - 10, 500 / 2 + 10, 400 / 2 + 10, fill='red')

# Create a rectangle inside the canvas
rectangle = canvas.create_rectangle(50, 0, 100, 50, fill='blue')

canvas.tag_bind(oval, "<Button-1>", oval_mouse_click)
canvas.tag_bind(rectangle, "<Button-1>", rec_mouse_click)
canvas.bind("<Button-1>", canvas_click)
canvas.pack()

win.mainloop()

输出

现在,当您单击画布上的某个对象(例如矩形对象)时,它将引发事件并调用 **rec_mouse_click(event)**,但它不会就此停止。它将进一步传播事件并调用 **canvas_click(event)**。因此,您将获得以下输出:

You have clicked the rectangle
You have clicked the Canvas

更新于: 2023年9月5日

610 次查看

开启您的 职业生涯

通过完成课程获得认证

立即开始
广告