ralfthewise has asked for the wisdom of the Perl Monks concerning the following question:
Hey all
I've got a really wierd problem. I have a grid that I display in TK. Simple grid of buttons. What that grid display changes everytime through an iteration of the program.
Here's the rub. It's not printing out each iteration, but rather waiting until it's run to completion and then printing out the final configuration.
I've tried $|=1 to shut off buffering
I've tried sleep(anytime), this just extends the time it takes all iterations to finish, and still waits till the final to print out.
I'm mad as hell...and I'm not going to take it anymore (Ah, invoking good old Jimmy Stewart always make me feel better)!
thanks,
john
Faster, faster, faster....till the thrill of speed overcomes the fear of death -Daniel Keys Moran
Re: refreshing a GUI
by busunsl (Vicar) on Jun 27, 2001 at 02:49 UTC
|
Try a $widget->update() on your widget holding the grid on each iteration.
This will handover the controll to Tk and update the widget. | [reply] [d/l] |
Re: refreshing a GUI
by ariels (Curate) on Jun 27, 2001 at 10:03 UTC
|
Tk only processes changes to widgets when it is in control (rather than your methods). What you need to do is to pause your program and let Tk's event loop clear up its backlog; this includes redisplays.
See the Tk::Widget docs for information about the methods idletasks and update. idletasks causes "most" updates to occur; the manual states it doesn't run updates "triggered by window size changes", but it sounds like it will be sufficient for your purposes. update causes Tk to clear its desk; it handles everything, including any pending user input.
Try calling idletasks (on the main window widget, say) after you finish informing Tk of all the updates you want to take place. Failing that, try calling update instead.
| [reply] [d/l] [select] |
Re: refreshing a GUI
by Abigail (Deacon) on Jun 27, 2001 at 02:48 UTC
|
I find your description of the problem a bit vague - I don't
really understand what the problem is. Where do you have
problems with? Printing out stuff? What are you printing to
where? Or do you have problems with changes in the appearance
of your GUI?
One should realize the only time the Tk library can update
the screen is when control is returned to it. As long as time
is spend in "user" code - and that includes the time
spend in sleep, Tk cannot update the
screen. Perhaps your problem is just a long running sub?
-- Abigail | [reply] [d/l] |
Re: refreshing a GUI
by Zapawork (Beadle) on Jun 27, 2001 at 06:37 UTC
|
Is the actual iteration stepping itself within the mainloop tk code? If not then it will not be executed until the mainloop exits.
I agree though.. if you posted your code it would really help in this problem.
Dave | [reply] |
Re: refreshing a GUI
by ralfthewise (Sexton) on Jun 27, 2001 at 17:53 UTC
|
Re-reading this post, I'm just going to say sorry. I'm not sure I even understand what I meant. Thanks for everything so far, and if you don't mind, I'll post the offending code and you guys can look over it.
sub go
{
foreach (1..5)
{
&neighbors_non_edge($radiovar);
&neighbors_corners($radiovar);
&neighbors_edge($radiovar);
&update_go_array();
&print_array();
}
}
This sub calls the five subs, in order, to complete a single iteration of the whole program. It's nested in a for loop because I want it to happen five times (printing out each time separately, clearing/refreshing the previous printout on the screen as it goes). This sub is outside the tk gui (so outside MainLoop) as are the five subs it calls.
The code for the button in the gui that calls sub go is
$start_button =$top->Button(-text => "Start the Process", -foreground
+=>"red", -command => sub{go()});
I've been looking into the tk::after module. Is that something that I should implement here? If so, where?
thanks again,
john
Faster, faster, faster....till the thrill of speed overcomes the fear of death -Daniel Keys Moran | [reply] [d/l] [select] |
|
What your loop is doing is telling Tk that you want to change the configuration of your widgets, but never giving it a chance actually to do it!
You should call $radiovar->idletasks (or perhaps $radiovar->update) somewhere in your foreach loop (say after update_go_array, if you've finished your reconfiguration by then). See the Tk::Widget manpage for details of these methods. This will give Tk a chance to display the updates you've made.
On a side note, why are you saying &subroutine() instead of subroutine()?
| [reply] [d/l] [select] |
|
Your cycling through five iterations before returning to the mainloop. Does this make sense to you? You are changing the contents of the widget 5 times and then returning to the mainloop for it to process the results.
Unless in some part of those subroutines there is a call back to the mainloop, i'm not sure how you would even do this, then the mainloop, which processes all tk events, would not ever see the changes that are happening.
If I am entirely missing the point here I apologize. This is just what i see.
Dave
| [reply] |
|
The Idea is not about where you store the Code. That could be
in a module or an evaled sub or whereever. The Idea is how you
*call* your code. You call your code by -command. That means the
MainLoop calls it on your behalf through that ref. So your
code runs *inside* the MainLoop. It does *not* enter the MainLoop
again before it returns. That's the error.
| [reply] |
Re: refreshing a GUI
by Aighearach (Initiate) on Jun 27, 2001 at 02:17 UTC
|
You should post the portion of the program that you're having trouble with.
-- Snazzy tagline here
| [reply] |
|
|