关于不同绑定方式的不同结果?

时间:2016-02-12 10:26:41

标签: python tkinter bind

在下面的代码中,我将键绑定到文本小部件。根据绑定的方式,我得到一个不同的结果,当一个' x'在窗口小部件中输入。

为什么bind和bind_all之间的输出存在差异? 我应该如何使用所有三种变体,以便它们都能得到相同的结果?

import tkinter as tk

class Q_bind(tk.Text):
    def __init__(self):
        tk.Text.__init__(self)

        self.bind("<Key>", self._insert_a)    #-> 'a\nx' with break a!
        #self.bind_class("<Key>", self._insert_a) # -> 'x' Replace with:
        #self.bind_class("Text", "<Key>", self._insert_a) # -> 'a'!!
        #self.bind_all("<Key>", self._insert_a)   # -> 'xa\n'
        print(self.bindtags())           #shows the bind-tags

    def _insert_a(self, event=None):
        print(event.char)
        self.insert('end' ,"a\n")
        return 'break'              #added

if __name__ == "__main__":
    app = Q_bind()
    app.pack(fill="both", expand='y')
    app.master.geometry('400x400')
    app.mainloop()

1 个答案:

答案 0 :(得分:1)

您不能使用所有三个绑定并获得相同的结果 1 ,因为结果取决于小部件绑定标记的顺序。

每个小部件都有一组有序的绑定标记。绑定实际上附加到这些标记而不是实际的小部件。恰好第一个绑定标记就是小部件的名称。

默认情况下,窗口小部件按以下顺序具有以下绑定标记:

  1. 小部件本身
  2. widget类(内部tk类,而不是tkinter类)
  3. 小部件顶层(或根窗口)
  4. “所有”
  5. 当小部件发生事件时,会发生以下四件事:

    1. 如果窗口小部件具有与事件匹配的绑定,则处理该绑定
    2. 如果窗口小部件具有与事件匹配的绑定,则处理该绑定
    3. 如果窗口小部件的顶层(或根)具有与事件匹配的绑定,则处理该绑定
    4. 如果对“all”有绑定,请处理该事件。
    5. 在任何时候,如果绑定返回文字字符串"break",则不会再处理任何绑定。如果不返回"break",则会处理所有四个事件处理程序。如果您的窗口小部件绑定返回"break",则不会处理类,顶层和“所有”绑定。

      在将<Key>bind_all绑定的具体情况下,会发生以下情况:

      1. 小部件没有与事件匹配的绑定,因此没有做任何事情
      2. 小部件类具有绑定,因此会被处理。在这种情况下,密钥的字母将插入到小部件
      3. 小部件的toplevel / root没有绑定,所以什么都没做。
      4. “all”标记具有绑定,因此它将插入"a\n"
      5. 由于"all"的绑定在绑定窗口小部件类之后发生,返回"break"无效,并且无法阻止插入“a”的默认行为除了您的自定义行为。

        绑定标签是一种非常漂亮的处理事件的方式。多年来,我在几种不同的语言中使用了至少六种不同的GUI工具包,没有任何东西能够接近tk绑定标签机制的强大功能。

        1 通过添加或删除绑定标记或更改绑定标记的顺序,您实际上可以为所有三种方法获得相同的行为。您可以使用bindtag方法执行此操作。很少需要这样做,但对于某些特殊情况它非常方便。