Perl 使用tcl在GUI中显示内容

Perl 使用tcl在GUI中显示内容,perl,user-interface,tcl,Perl,User Interface,Tcl,我是GUI新手,我试图在tcl中创建一个简单的GUI。它有一个按钮,按下该按钮时运行代码并在目录中生成输出“.l”文件。但我希望输出在GUI本身中打印。那么,我应该如何修改代码来完成任务呢 proc makeTop { } { toplevel .top ;#Make the window #Put things in it label .top.lab -text "This is output Window" -font "ansi 12 bold" text

我是GUI新手,我试图在tcl中创建一个简单的GUI。它有一个按钮,按下该按钮时运行代码并在目录中生成输出“.l”文件。但我希望输出在GUI本身中打印。那么,我应该如何修改代码来完成任务呢

proc makeTop { } {
    toplevel .top ;#Make the window
    #Put things in it
    label .top.lab -text "This is output Window" -font "ansi 12 bold"
    text .top.txt 
    .top.txt insert end "XXX.l"
    #An option to close the window.
    button .top.but -text "Close" -command { destroy .top }
    #Pack everything
    pack .top.lab .top.txt .top.but
}

label .lab -text "This is perl" -font "ansi 12 bold"
button .but -text "run perl" -command { exec perl run_me }
pack .lab .but

有人能帮我在GUI中显示输出文件XXX.l的内容吗?

对于只将结果打印到stdout的简单程序,很简单:
exec
返回程序的所有标准输出。因此,您只需读取
exec
调用的返回值:

proc exec_and_print {args} {
    .top.txt insert end [exec {*}$args]
}
但请记住,exec仅在程序退出后返回。对于希望输出立即显示在文本框中的长时间运行程序,可以使用
open
。如果传递给
open
的文件名的第一个字符是
|
,则
open
假定该字符串是要执行的命令行。使用
open
可以获得一个i/o通道,您可以从中连续读取:

proc long_running_exec {args} {
    set chan [open "| $args"]

    # disable blocking to prevent read from freezing our UI:
    fconfigure $chan -blocking 0

    # use fileevent to read $chan only when data is available:
    fileevent $chan readable {
        .top.text insert end [read $chan]

        # remember to clean up after ourselves if the program exits:
        if {[eoc $chan]} {
            close $chan
        }
    }
}
上面的
long\u running\u exec
函数立即返回并使用事件读取输出。这允许GUI在外部程序运行时继续运行,而不是冻结。要使用它,只需执行以下操作:

button .but -text "run perl" -command { long_running_exec perl run_me }

补充答复: 如果程序生成一个文件作为输出,而您只想显示该文件的内容,则只需读取该文件:

proc exec_and_print {args} {
    exec {*}$args

    set f [open output_file]
    .top.txt insert end [read $f]
    close $f
}

如果您知道文件是在哪里生成的,但不知道确切的文件名,那么请阅读
glob
手册,了解如何获取目录内容列表。

我是在目录中获取输出,而不是在GUI中,甚至是在按照建议进行更改时。您可能还需要告诉perl代码不要缓冲其输出。(或者使用expect的
unbuffer
脚本。)@Donal Fellows,我无法理解你的评论,请你详细说明一下。