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

发布于 2024-08-11 08:24:00 字数 387 浏览 1 评论 0原文

我有以下 python 代码...

import Tkinter

root = Tkinter.Tk()

root.tk.eval('puts {printed by tcl}')

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

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

欢呼

来自尼克的

I have the following python code...

import Tkinter

root = Tkinter.Tk()

root.tk.eval('puts {printed by tcl}')

It prints "printed by tcl" to the screen. How can I capture what the tcl interpreter prints to the screen into a python string.

This is a simplified example of what I am doing. I have an automation system written in python but a new piece of equipment that is controlled by a tcl api. Each tcl command prints things like "connected" or "connection failed", I need to be able to capture these into python strings, so the automation system can tell what is going on, so for example if the device does not connect the automation system can retry the connection command.

Cheers

From Nick

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏末染殇 2024-08-18 08:24:00

如果您正在运行的代码打印到屏幕上并且您使用 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

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

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

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

If the code you are running prints to screen and you're calling it with root.tk.eval() you can't capture that. However, You can redefine what "puts" does in the tcl code and have it do whatever you want. This is part of the beauty of Tcl -- there are no reserved words.

Simply create a proc named "puts" in the tcl interpreter, though make sure it has the exact same interface (ie: respects "-nonewline", can write to files, etc). When the puts normally prints to the screen you can instead have it do whatever you want, such as write to a socket or merely return the string it's supposed to print.

Roughly (untested, and ignoring the case with -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

It will require a little diligence to make sure you don't break the tcl code which expects a standard "puts" statement, but it's not that hard to do. Just make sure you have special cases for one argument, the first argument of "-nonewline", and where there are two arguments (file descriptor and string).

It might get complicated if you call eval and it does two puts statements, or does a puts and then some other code, since the result of the eval is the result of the last statement. However, you can work around that by having puts buffer its output to a global variable and then return the result of that variable each time you do an eval.

So, think outside the box a little and you can find a solution. Tcl is very flexible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文