Reputation: 1122
The code to reproduce my problem is given below. I named the file as 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
When I type
% wish
% source test.tcl
%
and then I click Command -> Test ... -> OK
which gives me
% hello world!
I don't get the prompt %
back after it prints hello world!
. Though I can still execute tcl commands in that space. For example:
% hello world!
puts "hi"
hi
%
which returns the prompt.
My question:
How to get the prompt %
back after tcl/tk executes the eval
command which prints hello world!
Upvotes: 2
Views: 4142
Reputation: 10211
The prompt %
came from tcl interpreter and shown in the terminal just because it's in interactive mode. If you run your script as wish test.tcl
you will never get %
.
You can implement your own interactive mode and call it after all initialization steps of your app. Here the example how it can be done:
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
}
}
}
Just call this function after Gui::test
execution and you;ll get your own prompt.
But even with this example the prompt will not be redrawn if a text will be printed to the terminal from some other procedure.
Upvotes: 3
Reputation: 8637
You never lost the %
prompt. Here's what's happening:
You have a prompt:
%
Then you print a string on that same line:
% hello world!
Your "current" prompt is still that same thing. The following command is "on" that prompt:
puts "hi"
Which, because it is running in tclsh and because you just inserted a newline, comes on the next line:
hi
And you get another prompt:
%
You didn't get "another" prompt from your GUI thing because puts "hello world"
wasn't processed by tclsh directly. Basically, as far as tclsh is concerned, the "hello world" came from Mars and screwed up your terminal. It doesn't even know that is there.
Maybe a better way to explain it is this: If your puts "hello world"
was printing to a file, then you would still have your %
prompt. But someone took those characters and shoved them onto your display (including the newline).
Upvotes: 3