Tcl 从fileevent调用的脚本访问更高级别

Tcl 从fileevent调用的脚本访问更高级别,tcl,tk,Tcl,Tk,我试图在Tcl/Tk脚本顶层的画布上进行绘制,但从fileevent调用内部绘制,如下所示: canvas .myCanvas {} proc plot_Data { myC inp } { $myC create rectangle {} } fileevent $inp readable [list plot_Data .myCanvas $inp ] pack .myCanvas 我发现fileevent(plot_Data)调用的脚本位于不同的空间 文件事件的脚本在调用filee

我试图在Tcl/Tk脚本顶层的画布上进行绘制,但从fileevent调用内部绘制,如下所示:

canvas .myCanvas {}

proc plot_Data { myC inp } { $myC create rectangle {} }

fileevent $inp readable [list plot_Data .myCanvas $inp ]

pack .myCanvas
我发现fileevent(plot_Data)调用的脚本位于不同的空间

文件事件的脚本在调用fileevent命令的解释器中在全局级别执行(在任何Tcl过程的上下文之外)

我不能让这两个人见面。我已经明确地把范围缩小到这样:plot_数据无法访问.myCanvas。问题:fileevent脚本如何在画布上绘图

顺便说一句,这部电影的目的是现场策划$inp是C程序的管道,该程序从测量设备读取数据。它正确地配置了fconfigure$inp-阻塞0-无缓冲。

回调脚本(不使用的跟踪除外)总是从全局命名空间的上下文中调用。它们无法看到上面的任何堆栈帧。这是因为它们在不受严格控制的时候被调用;不知道实际堆栈是什么,因此它被强制进入已知状态

但是,画布(和其他小部件)在全局名称空间中也有名称。如果小部件没有被破坏,并且可能确实在工作,您的回调肯定可以访问它们。您只是碰巧给了它一个要创建的空坐标列表,这通常不合法地用于画布项


由于您使用的是非阻塞I/O,因此需要注意,
get
在读取不完整的行时可能会返回空字符串。使用
fblocked
确定是否发生了部分读取;如果是这样的话,数据就在Tcl端的缓冲区中,等待行的其余部分出现,通常最好是进入睡眠状态,等待下一个fileevent触发


如果C程序处于完全缓冲模式,则可能会对您造成严重影响;将输出从C写入管道时,默认情况下是这样。在Tcl端设置缓冲不会影响它;您需要在C端使用,或者插入常规的
fflush
调用,或者使用Expect(它假装是一个交互目的地,尽管交互的复杂度要付出相当多的代价),或者甚至
unbuffer
(如果您可以找到副本)。

proc plot\u Data{myC inp}…
——这是您的真实代码还是打字错误?进程名和参数列表之间需要一个空格。此外,使用
fileevent
注册的脚本将按原样计算,而不是添加任何其他参数。因此,
plot\u Data.myCanvas
将给出一个关于缺少参数的错误。对不起,我应该说这是伪代码,glennjackman。只是想展示一下我是如何做到的。和@eviotto,tcl手册页中有一个例子:fileevent$chan readable[list GetData$chan]。我更改了我的帖子,以反映我是如何做的,脚本可以接受参数——因为它可以访问我传递给它的$inp文件描述符,并且它确实接收$myC as.myCanvas。然而,它不能在画布上绘制。是什么让你相信绘图数据不能在画布上绘制?如果您遇到错误,请包含错误消息。如果您只是看到“什么都没有”发生,那么问题可能在其他地方,包含真实代码(而不是伪代码)将有助于找到问题。