in reply to displaying program status in perl tk

GUI programs work in a different fashion than normal code. The Mainloop is the one updating the screen and if you don't return to it, nothing gets updated. So your while loop was poison for the GUI

#!/usr/bin/perl use warnings; use strict; use Tk; my ($no,$upper_no,$mw,$realend); $no=0; $upper_no=''; $mw = MainWindow->new; $mw->geometry("300x100"); $mw->title("PerlTk Test"); $mw->Label(-text => "Enter a 5 digit number") ->place(-relx => 0.0,-rely => 0.05); $mw->Entry(-takefocus => 1, -textvariable => \$upper_no, -width => 12) ->place(-relx => 0.50, -rely => 0.05); $mw->Button(-text => "Click to count upto that number and display them + below as you count", -wraplength => 250, -command => \&count) ->place(-relx => 0.5, -anchor => "center", -rely =>0.50); $mw->Label(-textvariable => \$no, -relief => 'sunken', -anchor => 'center') ->place(-relx =>0.0, -rely => 0.80, -relwidth => 1.0, -relheight = +> 0.2); MainLoop; sub count { if ($upper_no=~/^\d+$/ and $upper_no > 0) { if ($no < $upper_no) { $no++; } } }

Replies are listed 'Best First'.
Re^2: displaying program status in perl tk
by Anonymous Monk on Feb 04, 2009 at 16:13 UTC
    Hi jethro,
    Thanks for the quick response. With the modified code, I have to click the button each time to make the status message change. Isn't there some way of making the script update the mainloop from within a while loop as and when the status message changes?
      You can keep a reference to the label and update it directly. This is generally how you have to handle any progress/meter type stuff that needs to be updated in a loop. (This is untested but should be pretty close)
      my $counter_label = $mw->Label(-text => $no, -relief => 'sunken', -anchor => 'center') ->place(-relx =>0.0, -rely => 0.80, -relwidth => 1.0, -relheight = +> 0.2); ... sub count { if ($upper_no > 0) { $no = 0; while ($no < $upper_no) { $no++; $counter_label->configure(-text => $no); } } }
      Putting this code in your loop should do the trick. I haven't tested it.
      while(1) { last unless DoOneEvent($TK_DONT_WAIT); }
      DoOneEvent is the routine called from MainLoop.

      When passed the exported variable $TK_DONT_WAIT it returns true if there was an event to process, and false if otherwise. So DoOneEvent will continue to be called until there are no more events pending (and the only event pending would be the updating of your status bar). Then your program would continue on where it left off.

      Read more about the main loop here.