| 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 list(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 name in self.dict: |
| previous = dict[name] |
| else: |
| previous = OriginalCommand(self, name) |
| self.dict[name] = function |
| setattr(self.widget, name, function) |
| return previous |
| |
| def unregister(self, name): |
| if name in self.dict: |
| 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() |