2011-04-22 8 views
2

私の問題を再現するコードを以下に示します。私はTcl/Tk - evalを使ってコマンドを実行した後にプロンプ​​トを表示する方法は?

% wish 
% source test.tcl 
% 

入力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 

としてファイルを命名して、私は私に

% hello world! 

それは印刷した後、私は戻ってプロンプト%を得ることはありませんを与えるCommand -> Test ... -> OKをクリックしてくださいhello world!。私はまだその空間でtclコマンドを実行できます。例:

% hello world! 
puts "hi" 
hi 
% 

これはプロンプトを返します。

私の質問:Tcl/Tkは、あなたが%プロンプトを失ったことはありませんhello world!

+0

「Enter」キーを押すだけです。 – GrAnd

答えて

3

プロンプト%は、インタラクティブモードであるため、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実行した後、この関数を呼び出し、独自のプロンプトを取得でしょう。 しかし、この例でも、他のいくつかの手順からテキストが端末に出力される場合、プロンプトは再描画されません。

+0

ありがとうございます。私はこれを試してみましょう – Anand

+0

Gui :: interactiveからGui :: interactiveを呼び出すことができました。コマンド - >テスト - > OKを実行すると、プロンプトは 'tcl>'と表示されます。 tclshに何かを入力すると、私はプロンプト '%tcl>'を得る。 '%tcl>'の余分な '%'を取り除くための提案はありますか? – Anand

+0

対話モードではtclを実行しないでください。 'wish your_script.tcl'として実行します。 – GrAnd

3

を印刷しevalコマンドを実行した後、バックプロンプト%を取得する方法を 。ここで何が起こっているのです:

あなたはプロンプトを持っている:

%

その後、あなたはその同じ行に文字列を出力:

% hello world!

プロンプトがまだその同じであるあなたの「現在」もの。

それはTCLSHにし、あなただけの改行を挿入しているため実行されているために、次の行に来て、

puts "hi"

hi

次のコマンドを実行すると、そのプロンプト「上」でありますあなたがやった

%

:そして、あなたは別のプロンプトを取得しますputs "hello world"はtclshによって直接処理されなかったので、GUIのものから「別の」プロンプトを表示しないでください。基本的には、tclshに関する限り、 "hello world"は火星から来て、あなたのターミナルを台無しにしました。それはそこにあることさえ知りません。

多分それを説明するためのより良い方法はこれです:あなたのputs "hello world"ファイルに印刷した場合、あなたはまだあなたの%プロンプトを持っているでしょう。しかし、誰かがそれらの文字を取り出してディスプレイに表示しました(改行を含む)。

+0

それは意味があります。 tclshと直接通信する方法はありますか? – Anand

+0

プログラムから端末画面を「更新」する方法は考えられません。とにかく、なぜtclshで直接作業しなければならないのですか?良い説明のためには – drysdam

+0

+1。 Tclshはターミナルへの特別なバインディングをしないので、Ctrl + R(従来のターミナルリフレッシュシーケンス)のようなものは検出されず、プロンプトは印刷されません。あなたはいつもtkconを代わりに使ってみることもできますが、それは*非常に*異なるアプローチです(ターミナルエミュレーションをフルに行うグラフィックアプリケーションです)。 –

関連する問題