Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

How may I start/stop an endless loop with Tk?

Using a Tk widget to start such a loop, Tk will hang while the loop loops...endlessly. What I want is for another Tk widget to stop said loop. As below, where one Tk widget sets $foo to one and another Tk widget shall later unset it to zero.

while ($foo) { ...do something... }

Replies are listed 'Best First'.
Re: Tk for start/stop of endless loop?
by JamesNC (Chaplain) on Jan 18, 2004 at 15:52 UTC
    Maybe this will help, simple example:
    use Tk; use Tk::Button; use Tk::Label; use Tk::Text; my $foo = 0; my $break = 0; my $mw = tkinit; my $lbl1 = $mw->Label(-textvariable, \$foo)->pack(); my $txt1 = $mw->Text(-height, 1 )->pack(); my $btn1 = $mw->Button( -text, 'Start', -command, \&foo )->pack; MainLoop; #sub below the main sub foo { $btn1->configure(-text, 'Type quit in the text box to stop!'); while(1){ $foo++; $break = $txt1->get('0.0', 'end'); last if $break =~ /quit/ig; $mw->update; } $btn1->configure(-text, 'Start'); }


    JamesNC
Re: Tk for start/stop of endless loop?
by pg (Canon) on Jan 18, 2004 at 19:14 UTC

    From a design point of view, it is usually not a good idea to mix Tk program with end-less loops. I usually seperate endless processing away into a second script.

    So you have:

    • a GUI program allows to view progress or whatever.
    • a background script does the endless loop.

    In case, you think the mixture is not avoidable for whatever reason. Try two thing:

    • Do your endless loop in this way: 1) wrap the code inside the endless loop in a function. In this function there is no more endless loop, but only one iteration. 2) Using Tk::after to schedule the function once. 3) Inside the function, at the end of it, again use Tk::after to schedule itself once. The third step creates a endless loop, but it will not hang you GUI.
    • In your endless loop, periodically (could be once each loop) update Tk widget. This will avoid your Tk from hanging. Try this:
      use Tk; use Tk::ProgressBar; use strict; use warnings; my $count; my $mw = new MainWindow(-title => "demo"); $mw->Button(-command => [\&a_long_process, \$count], -text => "A Long +Process")->pack(); my $pb = $mw->ProgressBar( -from => 0, -to => 100000, -blocks => 100000, -colors => [0, 'green', 30000, 'yellow' , 60000, 'red'], -variable => \$count )->pack(); MainLoop; sub a_long_process { my $hash = {}; for (0..100000) { $hash->{$_} = $_; $count ++; $mw->update(); #try to comment and uncomment this ; } }