Skip to content
Advertisement

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?

Advertisement

Answer

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.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement