2016-11-04 3 views
2

Я определяю GCanvas, расширение Canvas. Мое намерение заключается в привязке к GCanvas на уровне класса. Он не работает.Confused about Tkinter bind_class

Я также пытался привязать к tk.Canvas, и он тоже не работает. Связывание с root или экземпляром 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() 

ответ

3

«класс» в bind_class относится к имени внутреннего класса, используемого в библиотеке Т.К., не имя класса питона. Точнее, в этом контексте он ссылается на тег связывания , который, оказывается, совпадает с именем 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)) 

Вы можете использовать bind_class следующим образом:

root.bind_class("GCanvas", "<Enter>", GCanvas.enter) 
root.bind_class("GCanvas", "<Leave>", GCanvas.leave) 

для получения дополнительной информации о связываемых тегах, чтобы эти ответы на некоторые другие вопросы Tkinter:

+0

Спасибо! Поэтому мне вообще не нужно определять класс Python; Мне просто нужно добавить к моим холстам уникальный привязку, не так ли? – Eduardo

+0

@Eduardo: правильный. Я рекомендую использовать класс для создания нового типа холста, но, строго говоря, вы не _need_. –