Tkinter是否可以将事件直接传递给父窗口小部件?
我有一块画布被其他画布的网格所覆盖(是复数?),我使用parent_canvas.create_window()
方法添加了它。我想要一些事件,例如鼠标释放事件,由父画布处理。
如果我只将事件绑定到父方法,则event.x
和event.y
坐标相对于捕获事件的子画布而来。
答案 0 :(得分:5)
Tkinter不会将事件传递给父窗口小部件。但是,您可以通过使用绑定标记(或" bindtags")来模拟效果。
我可以给出的最简单的解释是:当您向窗口小部件添加绑定时,您不会向窗口小部件添加绑定,而是绑定到"绑定标记"。此标记与窗口小部件的名称相同,但它实际上并不是窗口小部件。
窗口小部件有一个绑定标记列表,因此当窗口小部件上发生事件时,将按顺序处理每个标记的绑定。通常订单是:
请注意,该列表中的任何地方都没有"绑定父窗口小部件"。
您可以将自己的bindtags插入该顺序。因此,例如,您可以将主画布添加到每个子画布的绑定标记中。当你绑定到任何一个时,函数将被调用。因此,似乎将事件传递给父级。
这是一些用python 2.7编写的示例代码。如果单击灰色方块,您将看到打印出的两个内容,表明子画布上的绑定和主画布上的绑定都会触发。如果单击粉红色正方形,您将看到子画布绑定触发,但它会阻止父绑定触发。
这样,所有按钮点击都生效了#34;通过"到了父母。子画布可以通过返回" break"来控制父画面是否应该处理事件。如果它想打破链条"事件处理。
import Tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.main = tk.Canvas(self, width=400, height=400,
borderwidth=0, highlightthickness=0,
background="bisque")
self.main.pack(side="top", fill="both", expand=True)
# add a callback for button events on the main canvas
self.main.bind("<1>", self.on_main_click)
for x in range(10):
for y in range(10):
canvas = tk.Canvas(self.main, width=48, height=48,
borderwidth=1, highlightthickness=0,
relief="raised")
if ((x+y)%2 == 0):
canvas.configure(bg="pink")
self.main.create_window(x*50, y*50, anchor="nw", window=canvas)
# adjust the bindtags of the sub-canvas to include
# the parent canvas
bindtags = list(canvas.bindtags())
bindtags.insert(1, self.main)
canvas.bindtags(tuple(bindtags))
# add a callback for button events on the inner canvas
canvas.bind("<1>", self.on_sub_click)
def on_sub_click(self, event):
print "sub-canvas binding"
if event.widget.cget("background") == "pink":
return "break"
def on_main_click(self, event):
print "main widget binding"
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack (fill="both", expand=True)
root.mainloop()