'How to bind Tcl callbacks in Python

I was reading about msgcat.

Quote from the docs:

::msgcat::mcunknown locale src-string ?arg arg ...?

This routine is called by ::msgcat::mc in the case when a translation for src-string is not defined in the current locale. The default action is to return src-string passed by format if there are any arguments. This procedure can be redefined by the application, for example to log error messages for each unknown string. The ::msgcat::mcunknown procedure is invoked at the same stack context as the call to ::msgcat::mc. The return value of ::msgcat::mcunknown is used as the return value for the call to ::msgcat::mc. Note that this routine is only called if the concerned package did not set a package locale unknown command name.

How do I create a ::msgcat::mcunknown handler in my Python code using tkinter?



Solution 1:[1]

There are two steps required. Firstly, you use the register method to make the bridge from the Tcl side to your code.

def mcunknown_handler(locale, src, *args):
    # Stuff in here

handler = tcl.register(mcunknown_handler)

Then you need to get the Tcl side to call that at the right time. This needs a little care as we don't want to rename the command on the Tcl side because of how the Python binding works (it's more than a bit messy inside). Fortunately, we can delegate a Tcl command to another command easily.

tcl.eval("package require msgcat; interp alias {} msgcat::mcunknown {} " + handler)

As a whole thing:

>>> import tkinter
>>> tcl = tkinter.Tcl()
>>> def mcunknown_handler(locale, src, *args):
...     print("Hello", locale, src, "World")
...     return src
... 
>>> handler = tcl.register(mcunknown_handler)
>>> tcl.eval("package require msgcat; interp alias {} msgcat::mcunknown {} " + handler)
'msgcat::mcunknown'
>>> tcl.eval("msgcat::mc foo bar")
Hello en_gb foo World
'foo'

Your locale might be different, of course.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Donal Fellows