将 Python 变量传递给 `Tkinter.Tcl().eval()` [英] Pass Python variables to `Tkinter.Tcl().eval()`
问题描述
我可以获取一个 Tcl 脚本,然后从上述脚本中运行一个 proc
,如下所示:
导入Tkinter>>>tclsh = Tkinter.Tcl()>>>tclsh.eval('源{myscript.tcl}')>>>tclsh.eval('myproc')...[proc 的输出]>>>
但是,如果我想将变量传递给这个 proc,我必须这样做(假设 proc
将 dict
作为参数:
在 Tkinter 的上下文中,有没有更简单、更 Pythonic 的方法来做到这一点?我见过 变量类,但它们似乎没有 dict 样式的变量,甚至完全绑定到代码的 Tcl 解释器部分.
变量类是个好主意,但是没有具体的字典版本可用,有点难看,但你可以简单地使用字符串版本(并因此而影响性能,但这是可以修复的).
所以首先是简单的方法.Tcl dict 有一个字符串表示,并且可以自动转换为它的字符串 rep,所以如果你有一个需要 dict 的 proc,你可以简单地为 dict 传入字符串 rep,它就可以工作了.
interp = tkinter.Tcl()myvar = tkinter.StringVar()def pydict2tcldict(d):返回 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)
你当然可以通过提供一个特殊的 dict 变量包装器来让事情变得更好更快,而不是通过字符串 rep 的缓慢往返,请参阅变量类的实现.
但基本上 tkinter 只是缺少 _tkinter.c 模块中的一些转换函数(请参阅 AsObj
/FromObj
/CallArgs
),如果添加了适当的映射代码(微不足道),您可以简单地执行此操作并完成(并且相当快):
interp.call("myproc", d)
modules/_tkinter.c
的补丁在阅读 Tcl dict C API 手册页和 Python 映射 C-API (https://www.tcl.tk/man/tcl8.6/TclLib/DictObj.htm 和
I can source a Tcl script, and run a proc
from said script like so:
import Tkinter
>>> tclsh = Tkinter.Tcl()
>>> tclsh.eval('source {myscript.tcl}')
>>> tclsh.eval('myproc')
...[output of proc]
>>>
However, should I want to pass variables to this proc, I have to do it like so (assuming the proc
takes a dict
as a parameter:
>>> tclsh.eval('dict set spec num 10000')
>>> tclsh.eval('dict set spec time 10000')
>>> tclsh.eval('dict set spec rate 10')
Is there an easier, more-Pythonic way to do this from the context of Tkinter? I've seen the variable classes, but they don't seem to have a dict-style variable, or even tie into the Tcl interpreter part of the code at all.
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 ).
这篇关于将 Python 变量传递给 `Tkinter.Tcl().eval()`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!