[Tkinter-discuss] Convert Tk command string to Python callback

Russell E. Owen rowen at cesmail.net
Wed Nov 16 20:45:17 CET 2005


In article <20051114215954.07accbed.klappnase at web.de>,
 Michael Lange <klappnase at web.de> wrote:

> ...I just wondered if there is a way to ...access the associated python callback from the tk command 
> string...

I hope this helps. I've appended code that registers python functions to 
be called from tcl/tk. This is from my RO python package 
<http://www.astro.washington.edu/rowen/>, from RO.TkUtil.

-- Russell

class TclFunc:
    """Register a python function as a tcl function.
    Based on Tkinter's _register method (which, being private,
    I prefer not to use explicitly).
    
    If the function call fails, a traceback is printed.
    
    Please call deregister when you no longer
    want the tcl function to exist.
    """
    tkApp = None
    def __init__(self, func, debug=False):
        if self.tkApp == None:
            self.tkApp = _getTkWdg().tk
        self.func = func
        self.tclFuncName = "pyfunc%s" % (id(self),)
        self.debug = bool(debug)
        try:
            self.tclFuncName += str(func.__name__)
        except AttributeError:
            pass
        if self.debug:
            print "registering tcl function %s for python function %s" % 
(self.tclFuncName, func)
        self.tkApp.createcommand(self.tclFuncName, self)
    
    def __call__(self, *args):
        try:
            self.func(*args)
        except (SystemExit, KeyboardInterrupt):
            raise
        except Exception, e:
            sys.stderr.write("tcl function %s failed: %s\n" % 
(self.tclFuncName, e))
            traceback.print_exc(file=sys.stderr)
        
    def deregister(self):
        """Deregister callback and delete reference to python function.
        Safe to call if already deregistered.
        """
        if self.debug:
            print "%r.deregister()" % (self,)
        if not self.func:
            if self.debug:
                print "already deregistered"
            return
        try:
            self.tkApp.deletecommand(self.tclFuncName)
        except Tkinter.TclError, e:
            if self.debug:
                print "deregistering failed: %r" % (e,)
            pass
        self.func = None
    
    def __repr__(self):
        return "%s(%s)" % (self.__class__.__name__, self.tclFuncName)
    
    def __str__(self):
        return self.tclFuncName

def _getTkWdg():
    """Return a Tk widget"""
    global g_tkWdg
    if not g_tkWdg:
        g_tkWdg = Tkinter.Frame()
    return g_tkWdg



More information about the Tkinter-discuss mailing list