Pass Python variables to `Tkinter.Tcl().eval()`

前端 未结 1 1237
南旧
南旧 2021-01-21 17:27

I can source a Tcl script, and run a proc from said script like so:

import Tkinter
>>> tclsh = Tkinter.Tcl()
>>> tclsh.eval(\'sour         


        
相关标签:
1条回答
  • 2021-01-21 18:09

    The variable classes are a good idea, but there is no specific dict version of those available, which is a bit ugly, but you can simply use a string version (and take a performance hit due to it, but thats fixable).

    So the easy way first. A Tcl dict has a string representation and is convertible from and to its string rep automatically, so if you have a proc that needs a dict, you can simply pass in the string rep for the dict and it just works.

    interp = tkinter.Tcl()
    myvar = tkinter.StringVar()
    
    def pydict2tcldict(d):
        return tkinter._stringify(list(d.items()))
    
    d = {'num': 10000, 'time': 10000, 'rate': 10}
    myvar.set(pydict2tcldict(d))
    
    interp.eval("""source {myscript.tcl}
                   myproc $%s""" % myvar._name)
    

    You can of course make things a bit nicer and faster by providing a special dict variable wrapper instead of the slow round trip through the string rep, see the implementation of the variable classes.

    But fundamentally tkinter is just missing a few conversion functions in the _tkinter.c module (see AsObj/FromObj/CallArgs) if one added the appropriate code for mappings (trivial), you could simply do this and be done (and it would be reasonably fast):

    interp.call("myproc", d)
    

    The patch to modules/_tkinter.c should be pretty trivial, after reading the Tcl dict C API manpage and the Python mapping C-API (https://www.tcl.tk/man/tcl8.6/TclLib/DictObj.htm and https://docs.python.org/2/c-api/mapping.html ).

    0 讨论(0)
提交回复
热议问题