【问题标题】:Tcl/Tk - how to get the prompt after executing an command using eval?Tcl/Tk - 如何在使用 eval 执行命令后获得提示?
【发布时间】:2011-04-23 03:20:16
【问题描述】:

下面给出了重现我的问题的代码。我将文件命名为test.tcl

#-------------------------------------------------------------------
# test.tcl
#-------------------------------------------------------------------

namespace eval Gui {
}

proc Gui::test {} {
  toplevel .test
  wm title .test "Test"
  wm resizable .test 0 0 ;# not resizable

  # create a frame to hold the check widgets
  set f [frame .test.boolean -borderwidth 10] 
  pack $f -side top

  # OK and Cancel buttons
  button .test.ok -text "OK" -command [list Gui::Ok .test ]
  button .test.cancel -text "Cancel" -command [list Gui::cancel .test ]
  pack   .test.cancel .test.ok -side right

  bind .test <Return> {Gui::Ok .test ; break}
  bind .test <Escape> {Gui::cancel .test ; break}
}

proc Gui::Ok { arg } {
  set x [list puts "hello world!"]
  eval $x
  destroy $arg
}

proc Gui::cancel { arg } {
  destroy $arg
}

#-------------------------------------------------------------------
# Gui main window 
#-------------------------------------------------------------------
proc Gui::initialize { } {

  # build the frame which contains menu options
  frame .mbar -relief raised -bd 2
  frame .mdummy -width 200 -height 240
  pack .mbar .mdummy -side top -fill x

  # menu options
  menubutton .mbar.command -text Command -underline 0 -menu .mbar.command.menu
  pack .mbar.command -side left

  # menu under command options
  menu .mbar.command.menu -tearoff 0
  .mbar.command.menu add command -label "Test..." -command [list Gui::test]
}

#-------------------------------------------------------------------
# main code
#-------------------------------------------------------------------
Gui::initialize

当我输入时

% wish
% source test.tcl
%

然后我点击Command -&gt; Test ... -&gt; OK 这给了我

% hello world!

在打印 hello world! 后,我没有收到提示 %。虽然我仍然可以在那个空间执行 tcl 命令。例如:

% hello world!
puts "hi"
hi
%

返回提示。

我的问题: 如何在 tcl/tk 执行打印 hello world!eval 命令后返回提示符 %

【问题讨论】:

    标签: tcl tk


    【解决方案1】:

    提示 % 来自 tcl 解释器并显示在终端中只是因为它处于交互模式。如果你以wish test.tcl 运行你的脚本,你永远不会得到%

    您可以实现自己的交互模式,并在应用的所有初始化步骤之后调用它。这是如何完成的示例:

    proc Gui::interactive {} {
      set prompt1 "tcl>"
      set prompt2 "?"
      set cmd {}
      set prompt "$prompt1 "
      fconfigure stdin -blocking false -buffering line
      fileevent stdin readable {set Gui::stdinReady 1}
      while true {
        puts -nonewline $prompt
        flush stdout
        vwait Gui::stdinReady
        set str [gets stdin]
        lappend cmd $str
        set cmdStr [join $cmd "\n"]
        if {[info complete $cmdStr]} {
          set cmd {}
          if {$cmdStr != ""} {
            if {[catch {eval $cmdStr} result]} {
              puts stderr "ERROR: $result"
            } elseif {$result != ""} {
              puts $result
            }
          }
          set prompt "$prompt1 "
        } else {
          set prompt "$prompt2 "
        }
        if {[eof stdin]} {
          puts ""
          break
        }
      }
    }
    

    只需在Gui::test 执行后调用这个函数,你就会得到你自己的提示。 但即使在这个例子中,如果文本将从其他过程打印到终端,提示也不会重绘。

    【讨论】:

    • 谢谢。我会试试这个,让你知道
    • 我能够从 Gui::test 调用 Gui::interactive 并且当我执行 Command -&gt; Test ... -&gt; OK 时提示显示为 tcl&gt;;但是当我在 tclsh 中输入一些内容时,我会收到提示 % tcl&gt; 有什么建议可以去掉 % tcl&gt; 中多余的 % 吗?
    • 只是不要在交互模式下执行 tcl。以wish your_script.tcl 运行。
    【解决方案2】:

    您永远不会丢失% 提示符。以下是正在发生的事情:

    你有一个提示:

    %

    然后在同一行打印一个字符串:

    % hello world!

    您的“当前”提示仍然是一样的。以下命令是“打开”该提示符:

    puts "hi"

    因为它在 tclsh 中运行并且因为您刚刚插入了一个换行符,所以它出现在下一行:

    hi

    你会得到另一个提示:

    %

    你没有从你的 GUI 中得到“另一个”提示,因为puts "hello world" 没有被 tclsh 直接处理。基本上,就 tclsh 而言,“hello world”来自火星并搞砸了您的终端。它甚至不知道它的存在。

    也许更好的解释方法是:如果您的puts "hello world" 正在打印到一个文件,那么您仍然会有% 提示。但是有人拿走了这些字符并将它们推到了你的显示器上(包括换行符)。

    【讨论】:

    • 这是有道理的。有没有办法直接与 tclsh 通信?
    • 我想不出办法从程序中“刷新”终端屏幕,不。但是为什么还要直接在 tclsh 工作呢?
    • +1 以获得很好的解释。 Tclsh 不会对终端进行特殊绑定,因此不会检测到诸如 Ctrl+R(传统的终端刷新序列)之类的事情,并且不会打印提示。您总是可以尝试使用 tkcon 作为替代方案,但这是一种非常不同的方法(图形应用程序执行一些终端仿真,而不是完整的终端处理)。
    • 我正在开发一个应用程序,用户可以在其中使用 tclsh 和 gui 并混合使用它们;这就是我需要返回提示的原因。
    • 那么我认为您想要 GrAnd 的想法,即实现您自己的 tclsh shell,当您从 GUI 打印结果时,它可以知道。或者,您可以在其他地方打印 GUI 结果。
    猜你喜欢
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多