将 Python 变量传递给 `Tkinter.Tcl().eval()` [英] Pass Python variables to `Tkinter.Tcl().eval()`

查看:43
本文介绍了将 Python 变量传递给 `Tkinter.Tcl().eval()`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以获取一个 Tcl 脚本,然后从上述脚本中运行一个 proc,如下所示:

导入Tkinter>>>tclsh = Tkinter.Tcl()>>>tclsh.eval('源{myscript.tcl}')>>>tclsh.eval('myproc')...[proc 的输出]>>>

但是,如果我想将变量传递给这个 proc,我必须这样做(假设 procdict 作为参数:

<预><代码>>>>tclsh.eval('dict set spec num 10000')>>>tclsh.eval('dict 设置规范时间 10000')>>>tclsh.eval('dict 设置规格率为 10')

在 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.htmhttps://docs.python.org/2/c-api/mapping.html).

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆