在python或c ++中获取全局tcl数组

时间:2013-11-27 22:34:10

标签: c++ python tcl

我需要从tcl文件中导入现有信息(在tcl中保存变量),但我根本不熟悉tcl。我需要一个简单的解决方案(简称),它不需要超级健壮。 我有一个定义全局的tcl文件。这是一个小片段:

test.tcl:

global gP
set gP(1,1) {-2.77577 -2.66083 14.6978}
set gP(1,2) {-2.2751 -1.91189 13.5285}
set gP(1,3) {-1.46855 -1.21695 11.8953}
...
set gP(1,spline) [list \
  {p (-0.005623,0.225326,4.821360) t (-0.155507,0.806054,-0.571047) tx (0.000000,0.578079,0.815981)} \{p (-0.006889,0.231865,4.816766) t (-0.156976,0.809595,-0.565609) tx (0.000000,0.572709,0.819758)} \
...
  {p (2.224570,6.136620,-6.119510) t (0.901583,0.422393,0.093441) tx (0.000000,0.215995,-0.976394)} \
  ]
...
set gP(1,4) {-0.673205 -0.728409 10.3576}
set gP(1,5) {-0.261822 -0.476418 9.47673}
set gP(1,name) {path1}
...

我想要做的是从python或c ++运行tcl以使用该语言生成gP。所以像(在python中)

from Tkinter import Tcl
MYFILE = 'test.tcl'
tcl = Tcl()
gP = tcl.evalfile(MYFILE)

我的最终目标是将其转换为c ++,但我并不需要所有的gP。到目前为止我遇到的一个问题是,gP是一个数组,因此不会在Tkinter中以正常方式返回。

这不需要优雅,我只会使用一次或两次。我愿意在python中操作变量,在文本(或CSV)文件中打印出我需要的内容,然后将其读入c ++以填充变量。

修改

这样做就像patthoyts描述的是一个非常好的开始!我想我需要一个(或两个级别的解析?

我已经这样做了(gPathPoints和gP是相同的,只有不同的varname):

a  = eval(tcl.eval('''set r {};
  foreach k [array names gPathPoints] {
    lappend r "'$k': '$gPathPoints($k)'"
  };
  set r "{[join $r ,]}"
  '''))

Python吐出一个像样的字典,但键有点时髦:

'100,0': '-2.939 -3.02 15.136',
'100,1': '-2.77577 -2.66083 14.6978',
'100,10': '-0.00681104 0.408274 3.53018',
...

我可以用一个简单的c ++方法来解决这个问题,但我认为以下内容在tcl中会更容易:

'100,spline': '{p (-2.939000,-3.020000,15.136000) t (0.242924,0.657821,-0.712923) tx (0.000000,0.734938,0.678134)} {p (-2.934674,-3.008616,15.123467) t (0.250593,0.647200,-0.719955) tx (0.000000,0.743684,0.668531)}

1 个答案:

答案 0 :(得分:3)

使用python:

from Tkinter import *
# create an array in tcl
tk.eval('array set a {a 1 b 2 c 3 d "4 5 6"}')
s = tk.eval('array get a')

这会将数组作为字符串返回,但使用tcl列表格式:'d {4 5 6} a 1 b 2 c 3',因此您需要稍微重新解析它。您可以通过在Tcl中轻松解析来将其转换为python dict:

a  = eval(tk.eval('''set r {};
  foreach k [array names a] {
    lappend r "'$k': '$a($k)'"
  };
  set r "{[join $r ,]}"
  '''))

使用上面的示例代码,得到:

>>> a
{'a': '1', 'c': '3', 'b': '2', 'd': '4 5 6'}
>>> a['d']
'4 5 6'
>>>

如果数组值嵌入了引号,那么你必须更加小心引用处理,但这也很简单。

在C ++中我想你也可以评估array get $varname来获取一个Tcl列表对象。然后,您可以使用Tcl_ListObjGetElements和相关函数迭代键值对列表。