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