1

I have a perl tk routine calling a procedure from an imported perl module. The GUI hangs while the subroutine is being executed. Here is the code excerpt I am using. Can somebody please suggest a better way to do this so that the GUI is active while the procedure is running?

use Tk;
use package1;


$mw = MainWindow->new;
$mw->geometry("+10+10");
$mw->title("My notebook GUI");
my $mwFrame = $mw->Frame(-borderwidth => 2, -relief => 'ridge')->pack(-fill=> 'none',-fil=> 'x');
my $nb = $mwFrame->NoteBook(-dynamicgeometry => 'true',-ipadx => 20, -ipady => 20)->pack(-expand => 1,-fill => 'both');             
$page1 = $nb->add( 'Page1',     -label => 'Page 1' );
$page2 = $nb->add( 'Page2',     -label => 'Page 2' );
    $page1->pack();
    $page2->pack();

    $button1 = $page1->Button(-text => "Not Selected", -background => 'gray', -state => 'disabled')->pack(-side => 'right', -expand => 0);
    $button2 = $page2->Button(-text => "Not Selected", -background => 'gray', -state => 'disabled')->pack(-side => 'right', -expand => 0);

    my $obj = package1->new();
    my $obj->run();

In the above code, I am calling the run procedure from package1 to be executed. While the procedure takes a while, the GUI freezes, not allowing me to do anything on it. I cant even go from one page to the other in the notebook GUI.

Can somebody please guide me? I am a perl newbie.

Thanks.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • Can you stuff `$mw->update;` (or the less popular `$mw->idletasks;`) into your $obj? This post from Perlmonks explains it better http://www.perlmonks.org/?node_id=574002 – charlesbridge Oct 17 '13 at 11:22
  • I can try $mw->update; from my main code after calling the sub routine. But it only updates the main window after returning from the procedure. The alternative is to be able to execute "$mw->update" from the procedure itself. Now how will I be able to do that? – nrk chaitanya Oct 17 '13 at 11:30

2 Answers2

5

Welcome to the world of concurrent programming. In general terms, there are three main approaches here:

  1. Threads
  2. Fork / pipe
  3. Cooperative multitasking / event loop

There are pros and cons to each one.

Here's one example using the threads approach; I think this could be useful for you.

0

I am not too proficient with tk myself except for some basic stuff, but why do you want to run that Sub at that place? Normally i would assume you would want some button or other UI element to start the subroutine using some sort of -command => {$obj->run()}. What should allways work however is to fork from your main program for the execution. But without knowing what run() and $obj do it is hard to say if having them running parallel to your main Loop is feasible.

DeVadder
  • 1,404
  • 10
  • 18
  • No.. I actually have the sub running when the button is clicked. For the sake of simplicity, I did not include the code excerpt here. But even just calling a procedure hangs the GUI irrespective of whether the GUI is calling it or not.+ – nrk chaitanya Oct 17 '13 at 11:19
  • edit: By freezing you mean just the UI of your process is irresponsive? I thought you meant it completely froze your Computer. The UI not responding is because your process is busy with the sub, stopping it from taking care of anything else or even updating the UI. If you want your Ui to remain usable, you have to manage the concurrency yourself with either of the methods Mikko has suggested. Personally i would suggest forking as it is the easiest way (imho) and if you wanted to squeze out performance by managing threads by Hand, you should never have used Perl in the first place. – DeVadder Oct 17 '13 at 11:34