如何将事件传递给父 tkinter 小部件? [英] How to pass an event to parent tkinter widget?

查看:32
本文介绍了如何将事件传递给父 tkinter 小部件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible in Tkinter to pass an event directly to the parent widget?

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

I have a canvas wich is covered by a grid of other canvases (is that the plural?), which I added using the parent_canvas.create_window() method. I want some of the events, e.g mouse release events, to be handled by the parent canvas.

如果我只将事件绑定到一个父方法,event.xevent.y 坐标会相对于捕获事件的子画布出来.

If I only bind the event a parent method, the event.x and event.y coordinates come out relative to the child canvas which catches the event.

推荐答案

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

Tkinter does not pass events to parent widgets. However, you can simulate the effect through the use of bind tags (or "bindtags").

我能给出的最简短的解释是:当您向小部件添加绑定时,您不是在向小部件添加绑定,而是绑定到绑定标签".这个标签与小部件同名,但它实际上不是小部件.

The shortest explanation I can give is this: when you add bindings to a widget, you aren't adding a binding to a widget, you are binding to a "bind tag". This tag has the same name as the widget, but it's not actually the widget.

小部件有一个绑定标签列表,所以当小部件上发生事件时,每个标签的绑定都会按顺序处理.通常顺序是:

Widgets have a list of bind tags, so when an event happens on a widget, the bindings for each tag are processed in order. Normally the order is:

  1. 绑定在实际小部件上
  2. 小部件类上的绑定
  3. 在包含小部件的顶级小部件上的绑定
  4. 绑定所有"

请注意,该列表中没有任何地方是父小部件上的绑定".

Notice that nowhere in that list is "bindings on the parent widget".

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

You can insert your own bindtags into that order. So, for example, you can add the main canvas to the bind tags of each sub-canvas. When you bind to either, the function will get called. Thus, it will appear that the event is passed to the parent.

这是一些用 python 2.7 编写的示例代码.如果您单击一个灰色方块,您将看到打印出来的两件东西,显示子画布上的装订和主画布上的装订同时触发.如果您点击粉红色方块,您会看到子画布绑定触发,但它阻止父绑定触发.

Here's some example code written in python 2.7. If you click on a gray square you'll see two things printed out, showing that both the binding on the sub-canvas and the binding on the main canvas fire. If you click on a pink square you'll see that the sub-canvas binding fires, but it prevents the parent binding from firing.

这样,所有按钮点击实际上都传递"给了父级.子画布可以控制父画布是否应该处理事件,如果它想打破链条",则返回break".

With that, all button clicks are in effect "passed" to the parent. The sub-canvas can control whether the parent should handle the event or not, by returning "break" if it wants to "break the chain" of event processing.

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

这篇关于如何将事件传递给父 tkinter 小部件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆