1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
from Tkinter import *
class WidgetRedirector:
"""Support for redirecting arbitrary widget subcommands."""
def __init__(self, widget):
self.dict = {}
self.widget = widget
self.tk = tk = widget.tk
w = widget._w
self.orig = w + "_orig"
tk.call("rename", w, self.orig)
tk.createcommand(w, self.dispatch)
def __repr__(self):
return "WidgetRedirector(%s<%s>)" % (self.widget.__class__.__name__,
self.widget._w)
def close(self):
for name in self.dict.keys():
self.unregister(name)
widget = self.widget; del self.widget
orig = self.orig; del self.orig
tk = widget.tk
w = widget._w
tk.deletecommand(w)
tk.call("rename", orig, w)
def register(self, name, function):
if self.dict.has_key(name):
previous = dict[name]
else:
previous = OriginalCommand(self, name)
self.dict[name] = function
setattr(self.widget, name, function)
return previous
def unregister(self, name):
if self.dict.has_key(name):
function = self.dict[name]
del self.dict[name]
if hasattr(self.widget, name):
delattr(self.widget, name)
return function
else:
return None
def dispatch(self, cmd, *args):
m = self.dict.get(cmd)
try:
if m:
return m(*args)
else:
return self.tk.call((self.orig, cmd) + args)
except TclError:
return ""
class OriginalCommand:
def __init__(self, redir, name):
self.redir = redir
self.name = name
self.tk = redir.tk
self.orig = redir.orig
self.tk_call = self.tk.call
self.orig_and_name = (self.orig, self.name)
def __repr__(self):
return "OriginalCommand(%r, %r)" % (self.redir, self.name)
def __call__(self, *args):
return self.tk_call(self.orig_and_name + args)
def main():
root = Tk()
text = Text()
text.pack()
text.focus_set()
redir = WidgetRedirector(text)
global orig_insert
def my_insert(*args):
print "insert", args
orig_insert(*args)
orig_insert = redir.register("insert", my_insert)
root.mainloop()
if __name__ == "__main__":
main()
|