对Tkinter bind_class感到困惑

Edu*_*rdo 2 tkinter python-2.7 tkinter-canvas

我定义了GCanvas,它是Canvas的扩展.我的目的是在类级别绑定到GCanvas.它不起作用.

我也尝试绑定到tk.Canvas,它也不起作用.绑定到rootGCanvas实例或与GCanvas实例绑定工作正常.(这些替代方案对我来说都没有用,但我只是试着看看发生了什么.)运行OS X,El Capitan.

import Tkinter as tk

class GCanvas(tk.Canvas, object):

    def __init__(self, master, **kwargs):
        tk.Canvas.__init__(self, master, kwargs)

    @staticmethod
    def enter(e):
        print "enter", e.widget, e.x, e.y

    @staticmethod
    def leave(e):
        print "leave", e.widget

    @staticmethod
    def motion(e):
        print "motion", e.widget, e.x, e.y

approach = "bindinstance"

root = tk.Tk()
gc = GCanvas(root, width=400, height=300)
print "root is", root, "gc is", gc
gc.pack()

if approach == "bindGCanvas":
    print "binding to GCanvas"
    root.bind_class(GCanvas, '<Enter>', GCanvas.enter)
    root.bind_class(GCanvas, '<Leave>', GCanvas.leave)
    #root.bind_class(GCanvas, '<Motion>', GCanvas.motion)
elif approach == "bindCanvas":
    print "binding to Canvas"
    root.bind_class(tk.Canvas, '<Enter>', GCanvas.enter)
    root.bind_class(tk.Canvas, '<Leave>', GCanvas.leave)
    #root.bind_class(tk.Canvas, '<Motion>', GCanvas.motion)
elif approach == "bindinstance":
    print "binding to instance"
    gc.bind('<Enter>', GCanvas.enter)
    gc.bind('<Leave>', GCanvas.leave)
    #gc.bind('<Motion>', GCanvas.motion)
else:
    print "binding to root"
    root.bind('<Enter>', GCanvas.enter)
    root.bind('<Leave>', GCanvas.leave)
    #root.bind('<Motion>', GCanvas.motion)

root.mainloop()
Run Code Online (Sandbox Code Playgroud)

Bry*_*ley 5

"class"in bind_class是指tk库使用的内部类名,而不是python类名.更确切地,在这种情况下它是指一种结合标签,这恰好是相同的名称作为tk类,这也正好是相同的名称为核心的Tkinter类别之一(例如:Toplevel,Canvas,等等).

GCanvas在类级别绑定,最简单的方法是添加一个命名GCanvas为画布的绑定标记,如下例所示:

class GCanvas(tk.Canvas, object):
    def __init__(self, master, **kwargs):
        ...
        # get the current bind tags
        bindtags = list(self.bindtags())

        # add our custom bind tag before the Canvas bind tag
        index = bindtags.index("Canvas")
        bindtags.insert(index, "GCanvas")

        # save the bind tags back to the widget
        self.bindtags(tuple(bindtags))
Run Code Online (Sandbox Code Playgroud)

然后您可以这样使用bind_class:

root.bind_class("GCanvas", "<Enter>", GCanvas.enter)
root.bind_class("GCanvas", "<Leave>", GCanvas.leave)
Run Code Online (Sandbox Code Playgroud)

有关绑定标记的更多信息,请参阅以下一些其他tkinter问题的答案: