For Programmers: Free Programming Magazines  


Home > Archive > Tcl > September 2006 > Nesting behvior of tkwait









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Nesting behvior of tkwait
Dave Dean

2006-09-27, 10:00 pm

Hi all,
I'm concerned about some potential pitfalls I might run into using the
tkwait command. It seems like a very useful command, especially the "tkwait
variable" option. However, I'm wondering if it's dangerous to use "tkwait
variable" inside a procedure called by a binding. I tried this little
experiment:

button .button1 -text "1" -command "waitVar 1"
button .button2 -text "2" -command "waitVar 2"
button .continue -text "CONTINUE" -command "incr cont"
text .text -height 1m
pack .text -side bottom
pack .continue .button2 .button1 -side bottom -fill x
set var1 0; set var2 0; set cont 0
proc waitVar {num} {
tkwait variable cont
.text insert end $num
}

When run, this seems to allow a queue of commands to be built up. If press
"1" three times, I get three 1's when I press continue. If I press "1212"
then continue, I get "2121" in the text box. This is the behavior I'd
expect (I think).

Now, If I change the proc to the following:
proc waitVar {num} {
set cont $num
tkwait variable cont
.text insert end $num
}

If I press "111", I'd expect to get this displayed in the text box when I
press "2". It seems that pressing "2" would cause "cont" to change, which
should trigger the "tkwait variable" statements, and allow the "111" to be
displayed. Why does this not seem to be the case? My only hunch is that,
even though "cont" has been updated, the whole thing won't trigger until the
process that updates "cont" exits. If that's the case, is there any way to
force the triggering?

Thanks,
Dave




Bruce Hartweg

2006-09-27, 10:00 pm

Dave Dean wrote:
> Hi all,
> I'm concerned about some potential pitfalls I might run into using the
> tkwait command. It seems like a very useful command, especially the "tkwait
> variable" option. However, I'm wondering if it's dangerous to use "tkwait
> variable" inside a procedure called by a binding. I tried this little
> experiment:


you are indeed seeing the pitfalls with the nesting of waits, i.e.
thay *are* nested, and only unroll in the (reverse) order given,
so can do things very opposite of what you want.

They are very handy for short asynchrounous bits that you want
to behave like they were synchronous (i,e, simple dialogs for asking
yes/no, or picking a file or what not - then the main part of your
code can be

do stuff..
set name [tk_getOpenFile ....]
do more stuff with name

instead of the open having to take a callback, and you splitting up
the pre and post work, and saving/sending that state between the two etc

but in general I would not use it for long running, or interleaved
areas of you application, for those it is much better to break
apart the functionality and setup the event handlers so that
things are processed in the order of the events occurring,
as opposed to the order you are looking for them.

If you want something to happend when variables change, use a trace,
when sockets are readable, use a fileevent, etc.

>
> button .button1 -text "1" -command "waitVar 1"
> button .button2 -text "2" -command "waitVar 2"
> button .continue -text "CONTINUE" -command "incr cont"
> text .text -height 1m
> pack .text -side bottom
> pack .continue .button2 .button1 -side bottom -fill x
> set var1 0; set var2 0; set cont 0
> proc waitVar {num} {
> tkwait variable cont
> .text insert end $num
> }
>
> When run, this seems to allow a queue of commands to be built up. If press
> "1" three times, I get three 1's when I press continue. If I press "1212"
> then continue, I get "2121" in the text box. This is the behavior I'd
> expect (I think).
>
> Now, If I change the proc to the following:
> proc waitVar {num} {
> set cont $num
> tkwait variable cont
> .text insert end $num
> }
>
> If I press "111", I'd expect to get this displayed in the text box when I
> press "2". It seems that pressing "2" would cause "cont" to change, which
> should trigger the "tkwait variable" statements, and allow the "111" to be
> displayed. Why does this not seem to be the case? My only hunch is that,
> even though "cont" has been updated, the whole thing won't trigger until the
> process that updates "cont" exits. If that's the case, is there any way to
> force the triggering?


nope - remember that the event loop is just that a loop so each vwait
(or tkwait variable) starts a loop of event processing and the loop termination
is the check of the variable being changed, so the processing of an event
is what's going on *inside* the loop, so until that finishes it's not
checking that end condition.


If you post a little more about your actual app, and what you are
trying to accomplish, there can be very useful advice given on the
best way to go about it.

Bruce
Donald Arseneau

2006-09-28, 4:02 am

"Dave Dean" <dave.dean@xilinx.com> writes:

> When run, this seems to allow a queue of commands to be built up.


It is a stack, not a queue.

> proc waitVar {num} {
> set cont $num
> tkwait variable cont
> .text insert end $num
> }


As Bruce says, the event handlers do stack up: "recursive event loops".

But I'll mention that you forgot "global cont", so your test didn't
prove anything anyway.


--
Donald Arseneau asnd@triumf.ca
Markus Triska

2006-09-28, 7:02 pm

Donald Arseneau <asnd@triumf.ca> writes:

> "global cont"


Doesn't change the outcome. There's another thing that would prevent
the result OP expected: tkwait variable triggers on all modifications,
also if the variable is set to its own (previous) value.


Best wishes, Markus Triska
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com