将 python 变量传递给 tcl

Pass python variable to tcl

我在 python 中使用 Tkinter 模块,并试图将 python 中的变量传递给 tcl

我知道我可以传递像

这样的变量
tclsh = Tkinter.Tcl()
num = 1 
tclsh.eval("set num {}".format(1))

我还有什么办法可以做到这一点吗?由于我要传递很多变量,所以我希望有一个优雅的方式来传递变量

喜欢这个postPass Python variables to `Tkinter.Tcl().eval()`

但是我试过了,它对我不起作用

我认为无论如何都不能将变量批量添加到 tcl 解释器中。但是,您可以使用 call 而不是使用 eval 和字符串格式。 call 优于 eval 的优点是 call 会处理正确引用所有参数的细节。

call 通过提供每个单词作为参数,您可以像在 tcl 中一样调用 tcl procs。您问题中的示例如下所示:

tclsh.call("set", "num", num)

但是,这仅适用于字符串和数字等基本数据类型。列表和字典等对象不会自动转换为底层的 tcl 数据类型。

这是一个稍微简洁的版本,它将对 Tcl 全局变量的访问封装为 Python class:

import tkinter

class TclGlobalVariables(object):
    def __init__(self, tclsh):
        self.tclsh = tclsh

    def __setattr__(self, name, value):
        if name == "tclsh":
            object.__setattr__(self, name, value)
        else:
            # The call method is perfect for this job!
            self.tclsh.call("set", "::" + name, str(value))

    def __getattr__(self, name):
        if name == "tclsh":
            return object.__getattr__(self, name)
        else:
            # Tcl's [set] with only one argument reads the variable
            return self.tclsh.call("set", "::" + name)

演示它:

tcl = TclGlobalVariables(tkinter.Tcl())
# Write to a Tcl variable
tcl.x = 123
# Read from it
print("From Python: x =", tcl.x)
# Show that it is really there by sending commands to the underlying Tcl interpreter
tcl.tclsh.eval('puts "From Tcl: x = $x"')
# Show that manipulations on the Tcl side are carried through
tcl.tclsh.eval('incr x 2')
print("From Python again: x =", tcl.x)
# Show that manipulations on the Python side are carried through
tcl.x += 3
tcl.tclsh.eval('puts "From Tcl again: x = $x"')

产生此输出:

From Python: x = 123
From Tcl: x = 123
From Python again: x = 125
From Tcl again: x = 128

请注意,这假定您仅在 Tcl 端访问简单的全局变量(不是命名空间变量和数组)并且不处理类型映射。更深层次的映射是可能的……但会变得非常复杂。