使用 tkinter 时如何将 tcl 中的 stdout 获取到 python 字符串变量中?

2 python tkinter tcl

我有以下 python 代码...

import Tkinter

root = Tkinter.Tk()

root.tk.eval('puts {printed by tcl}')
Run Code Online (Sandbox Code Playgroud)

它会在屏幕上打印“printed by tcl”。如何将 tcl 解释器打印到屏幕上的内容捕获到 python 字符串中。

这是我正在做的事情的简化示例。我有一个用 python 编写的自动化系统,但有一个由 tcl api 控制的新设备。每个 tcl 命令都会打印“已连接”或“连接失败”之类的内容,我需要能够将这些内容捕获到 python 字符串中,以便自动化系统可以知道发生了什么,例如,如果设备未连接自动化系统可以重试连接命令。

干杯

来自尼克

Bry*_*ley 5

如果您正在运行的代码打印到屏幕上并且您使用 root.tk.eval() 调用它,则您无法捕获该代码。但是,您可以在 tcl 代码中重新定义“puts”的作用,并让它执行您想要的任何操作。这是 Tcl 之美的一部分——没有保留字。

只需在 tcl 解释器中创建一个名为“puts”的过程,但要确保它具有完全相同的接口(即:尊重“-nonewline”,可以写入文件等)。当 put 通常打印到屏幕上时,您可以让它执行您想要的任何操作,例如写入套接字或仅返回它应该打印的字符串。

粗略地(未经测试,并忽略带有 -nonewline 的情况):

root.tk.eval('''
rename puts original_puts 
proc puts {args} {
    if {[llength $args] == 1} {
        return "=> [lindex $args 0]"
    } else {
        eval original_puts $args
    }
}
''')

foo = root.tk.eval('puts "hello, world"')
print foo
=> hello, world
Run Code Online (Sandbox Code Playgroud)

这需要一点努力来确保您不会破坏需要标准“puts”语句的 tcl 代码,但这并不难做到。只需确保一个参数有特殊情况,即“-nonewline”的第一个参数,以及有两个参数(文件描述符和字符串)的情况。

如果您调用 eval 并且它执行两个 put 语句,或者执行一个 put 然后执行一些其他代码,则情况可能会变得复杂,因为 eval 的结果是最后一个语句的结果。但是,您可以通过将其输出缓冲到全局变量中来解决这个问题,然后在每次执行 eval 时返回该变量的结果。

因此,跳出框框思考一下,你就能找到解决方案。Tcl非常灵活。