问题
I define GCanvas, an extension of Canvas. My intention is to bind to GCanvas at the class level. It isn't working.
I also tried to bind to tk.Canvas and it doesn't work either. Binding to root
or to the GCanvas instance works fine. (Neither of this alternatives is useful to me, but I just tried them to see what happened.). Running 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()
回答1:
The "class" in bind_class
refers to the internal class name used by the tk library, not the python class name. More precisely, in this context it refers to a bind tag, which happens to be the same name as the tk class, which also happens to be the same name as one of the core Tkinter classes (eg: Toplevel
, Canvas
, etc).
To bind to GCanvas
at the class level, the simplest thing would be to add a bind tag named GCanvas
to your canvas, as in the following example:
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))
You can then use bind_class
like so:
root.bind_class("GCanvas", "<Enter>", GCanvas.enter)
root.bind_class("GCanvas", "<Leave>", GCanvas.leave)
For more information about bind tags, see these answers to some other tkinter questions:
- https://stackoverflow.com/a/11542200/7432
- https://stackoverflow.com/a/3513906/7432
来源:https://stackoverflow.com/questions/40421993/confused-about-tkinter-bind-class