【问题标题】:Display contents in the GUI using tcl使用 tcl 在 GUI 中显示内容
【发布时间】:2026-01-01 11:20:03
【问题描述】:

我是 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 的内容???

【问题讨论】:

    标签: perl user-interface tcl


    【解决方案1】:

    对于仅将其结果打印到标准输出的简单程序,这很简单: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_running_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,我无法理解您的评论,请您详细说明一下。