Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Doing two things at once in TK

9 views
Skip to first unread message

Krzysztof Kozminski

unread,
Jul 19, 1996, 3:00:00 AM7/19/96
to g...@mcs.com

Russel Dalenberg wrote:
>
> I'm trying to write a simple TK program that will display a listbox, accept
> a user selection from that listbox, and run a Unix command that will look
> up some information based on that selection.
>
> Since this process may take some time, when the user makes his selection
> I want to start up an animation, and then stop the animation when the
> Unix task finishes.
>
> I've tried using "after" and "tkwait" in various combinations, but no
> matter what I try, I find everything grinding to a halt while the loop-up
> task is runnig, and the animation runs after.

You're probably starting the process with 'exec', which blocks until the
spawned process exits. On the other hand, if you use 'exec ... &' to run
in the background, you'll never know when it is done (and what was its
exit status).

Try using the Expect extension which lets you both to spawn a process in
the background and find out when it's done (or use tclX, with which you can
do the same thing as well).

BTW, beware of overusing tkwait - due to the way the interpreter works, you
might find yourself unexpectedly blocked in a situation where, due to some
or other reasons, the tkwait commands are executed in a sequence like this:

tkwait variable A; action1
...
tkwait variable B; action2
...
tkwait variable A; action3

NOTE: the above is just the sequence of executions, NOT actual code!
If A changes, then only action3 is executed, since the trigger to action1
is shielded by the tkwait on variable B. On the other hand, in a sequence:

tkwait variable A; action1
...
tkwait variable A; action3

a single change of A will execute both actions.

I've been told that the above behavior is the way it has been designed to
work. Luckily, most interesting things can be done with traces on variables.

--
Krzysztof Kozminski _ _ National Semiconductor Corp.
k...@nsc.com / \' \ 2900 Semiconductor Drive
Phone: 408-721-8291 //\ \// P.O. Box 58090 M/S D3-677
Fax: 408-773-0978 \_,\_/ Santa Clara, CA 95052-8090, USA.
===================
"Applying computer technology is simply finding the right wrench to pound
in the correct screw." - source unknown (to me - KK)

Peter Ruczynski

unread,
Jul 22, 1996, 3:00:00 AM7/22/96
to Russel Dalenberg, rucz...@x500.bt.co.uk

Russel Dalenberg wrote:
>
> I'm trying to write a simple TK program that will display a listbox, accept
> a user selection from that listbox, and run a Unix command that will look
> up some information based on that selection.
> [snip]
>
> Anybody got any pointers on how I can do this simple task?

Don Libes Expect package is THE way to control external processes so
I suggest you look into using that. Expect will allow you to run your
UNIX processes whilst allowing you to carry on processing your script.
It's very powerful and should provide you with more than enough
functionality for what you want to do.

There is a beta version at
ftp://ftp.cme.nist.gov/pub/expect/beta.tar.gz which will run
with tcl 7.5 although I haven't used it yet so I don't know if it's
a loadable module or if you still have to compile it into a seperate
shell. There's also an excellent book on expect by Don called
Exploring Expect, it's one of the O'Reilly series:
http://www.ora.com/catalog/expect

Pete.
--
Peter Ruczynski
work: rucz...@x500.bt.co.uk
home: pe...@softbase.demon.co.uk
play: http://www.wokingham.luna.net/~graeme/as.htm

wi...@news.sns-felb.debis.de

unread,
Jul 23, 1996, 3:00:00 AM7/23/96
to

Krzysztof Kozminski (k...@berlioz.nsc.com) wrote:

: Russel Dalenberg wrote:
: >
: > I'm trying to write a simple TK program that will display a listbox, accept
: > a user selection from that listbox, and run a Unix command that will look
: > up some information based on that selection.
: >
: > Since this process may take some time, when the user makes his selection

: > I want to start up an animation, and then stop the animation when the
: > Unix task finishes.
: >
: > I've tried using "after" and "tkwait" in various combinations, but no
: > matter what I try, I find everything grinding to a halt while the loop-up
: > task is runnig, and the animation runs after.
:
: You're probably starting the process with 'exec', which blocks until the
: spawned process exits. On the other hand, if you use 'exec ... &' to run
: in the background, you'll never know when it is done (and what was its
: exit status).
:
: Try using the Expect extension which lets you both to spawn a process in
: the background and find out when it's done (or use tclX, with which you can
: do the same thing as well).
:
: [...]
:

As Russel wrote, the Unix command started by Tcl/Tk returns
some information. So he can execute it with the Tcl command
'open' :-)

proc get_data_from_ls {fid} {
global stop_anim
if {[gets $fid line] < 0} {
close $fid
set stop_anim true
return
}
# process the line from ls
puts stdout "LS: $line"
}

proc animate {} {
global stop_anim
if {$stop_anim} {
# Here you reset your app to be idle
return
}

# Do the animation

after 50 animate
}

set fid [open "|ls -l" "r"]
fconfigure $fid -blocking no -buffering line
fileevent $fid readable "get_data_from_ls $fid"

global stop_anim
set stop_anim false
after 50 animate

# Here you set your app to be busy

This way, the Tcl/Tk application spends it's time in the
event loop. The termination of the child process causes EOF
on the pipe, even if the child in questions doesn't output
anything. And the zombie is cleaned up at close, because for
pipe channels close calls wait(2) (or one of it's family).


Until later, Jan

--
#define OPINIONS "they are all mine - not those of debis or daimler-benz"

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================== wi...@sapserv.debis.de (Jan Wieck) #

Donal K. Fellows

unread,
Jul 24, 1996, 3:00:00 AM7/24/96
to

In article <4sn44u$h...@mercury.mcs.com>, Russel Dalenberg <g...@MCS.COM> wrote:
> I'm trying to write a simple TK program that will display a listbox, accept
> a user selection from that listbox, and run a Unix command that will look
> up some information based on that selection.
>
> Since this process may take some time, when the user makes his selection
> I want to start up an animation, and then stop the animation when the
> Unix task finishes.

You probably want to make sure that the only action possible during
the lookup is cancel...

> I've tried using "after" and "tkwait" in various combinations, but no
> matter what I try, I find everything grinding to a halt while the loop-up
> task is runnig, and the animation runs after.

You're exec-ing the process in the foreground, so naturally wish will
block...

> Anybody got any pointers on how I can do this simple task?

For a general Unix command, you really need to be using expect.

However, if you are only going to be using non-interactive commands
(so they don't require being attached to a tty) then you can probably
get away with using:

set file [open "|$cmd" r]

and using fileevents to activate reads from the command pipeline when
data is available (this takes a bit of work, but can produce excellent
results when working)

Donal.
--
Donal K. Fellows, (at work) | Donal K. Fellows, (at home)
Dept. of Computer Science, | 6, Randall Place, Heaton,
University of Manchester | Bradford, BD9 4AE
U.K. Tel: ++44-161-275-6137 | U.K. Tel: ++44-1274-401017
fell...@cs.man.ac.uk (preferred) | do...@ugglan.demon.co.uk (if you must)
--------------------------------------------------------------------------
<http://r8h.cs.man.ac.uk:8000/> for my home page

0 new messages