2011-04-22 1 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 :: test에서 Gui :: interactive를 호출 할 수 있었고'Command -> Test ... -> 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을 대안으로 사용해 볼 수도 있지만, 이것은 매우 다른 접근법이다. (그래픽 애플리케이션은 완전한 터미널 처리가 아닌 일부 터미널 에뮬레이션을하고있다.) –