* Frank <
kra...@gmail.com>
| I have the following situation:
>
| 1) An application with a GUI and a TCL console built in.
| 2) I wrote a proc that is executed within the TCL console. It creates
| another top level window.
| 3) The proc is called within multiple levels of execution hierarchy
| (nested procedures).
>
| I would like the user to make changes in the GUI and based on the
| inputs take action but this has to be done at the execution level
| (stack) where my proc was called (3 above).
>
| I can not use a button in the GUI to call a proc to take action as it
| seems the GUI is at the top level of execution (#0) and the proc call
| will not be at the same execution level where my proc was called
| above.
>
| How can I detect the action in the GUI (keeping the main application
| GUI and my top level window (2 above) active and don't leave the
| execution stack where my procedure was called?
Unless you're running multi-threaded (do you?), you need to trigger an
'update' to actually give the GUI a chance to do anything.
If you simply loop inside a4, the GUI has no chance to do anything.
proc a4 {} {
# whatever
for {set i 0} {$i <= 20} {incr i} {
update ; # GUI takes action
# now check global variables indicating GUI changes
if {$::stop} {
puts "Stop button pressed"
return
}
if {$i == 10} {my_proc_call}
}
}
set ::stop 0
button .stop -command {set ::stop 1}
Note however that the 'update' may have unwanted side effects like
e.g. re-entering the proc-stack which leads to a4 etc (see
http://wiki.tcl.tk/1255 "Update considered harmful"), and that while the
loop is active (eg while in calling 'my_proc_call'), the GUI does not
react at all.
Either run multi-threaded or redesign the proc stack via coroutines (as
someone else suggested) or iterate via 'after':
proc a4 {i} {
if {$::stop || $i >= 20} {
# done
return
}
if {$i == 10} {my_proc_call}
after 0 [list a4 [incr i]]
# GUI gets a chance after we return
}
HTH
R'