如何在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