如何将事件传递给父窗口小部件

发布于 2021-01-29 14:59:38

在Tkinter中是否可以将事件直接传递给父窗口小部件?

我有一个画布,该画布被其他画布的网格覆盖(是复数吗?),我使用parent_canvas.create_window()方法添加了该画布。我希望某些事件(例如鼠标释放事件)由父画布处理。

如果仅将事件绑定到父方法,则event.xevent.y坐标相对于捕获事件的子画布而言。

关注者
0
被浏览
75
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    Tkinter不会将事件传递给父窗口小部件。但是,您可以通过使用绑定标签(或“ bindtags”)来模拟效果。

    我能给出的最简短的解释是:将绑定添加到窗口小部件时,不是在将绑定添加到窗口小部件,而是将其绑定到“绑定标签”。该标签与小部件具有相同的名称,但实际上不是小部件。

    窗口小部件具有绑定标签的列表,因此,当窗口小部件上发生事件时,将按顺序处理每个标签的绑定。通常,顺序为:

    1. 实际小部件上的绑定
    2. 小部件类上的绑定
    3. 包含窗口小部件的顶级窗口小部件上的绑定
    4. 对“所有”的绑定

    请注意,该列表中没有任何地方是“父窗口小部件上的绑定”。

    您可以按此顺序插入自己的绑定标签。因此,例如,您可以将主画布添加到每个子画布的绑定标签中。当您绑定到任何一个时,该函数都会被调用。因此,似乎事件已传递给父级。

    这是一些用python
    2.7编写的示例代码。如果单击灰色正方形,则会看到打印出的两件事,这表明子画布上的装订和主画布上的装订同时发生。如果单击一个粉红色的正方形,则会看到子画布绑定被触发,但是它阻止了父绑定的触发。

    这样,所有按钮单击实际上都“传递”给了父级。子画布可以控制父级是否应处理事件,如果要“中断事件处理的链”,则返回“中断”。

    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()
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看