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

I have some issues with TK MainLoop contorl. i have 2 perl scripts(.pl) and 2 perl modules(.pm) created by myself.

script 1. mainprog.pl has TK widgets (button) and depending on which button the user 'clicks', main script will run that perticular (2nd) perl script.

script2. this 2nd perl script in turn calls other 2 perl modules and each module has its own TK mainloop contorl. in this script i have called module1 first and module2 next

the problem is when i run the script#2 first, everything works fine without any problem. however if i run the script#1 first which calls script#2 then the module1 and module2 is activated simultaniously.

in other words if i run the script#2 then module1 is run first and WAITS for 1 TK mw to finish. then only it runs second module. however if i run this from main script then both module1 and module2 are run at a time.

how do i fix this?

Edit: g0n - basic markup

Replies are listed 'Best First'.
Re: MainLoop control
by zentara (Cardinal) on Dec 12, 2007 at 13:52 UTC
    Another option, is to name your maindows in the other Tk scripts differently (like $mw1, $mw2,$mw3 , etc, then don't call MainLoop in those secondary windows, but do-one-loop manually. Its a bit more complex than fork-and-exec, but you asked for manual mainloop control.
    #!/usr/bin/perl use warnings; use strict; use Tk qw/tkinit DoOneEvent exit DONT_WAIT ALL_EVENTS/; my $mw = tkinit; $mw->Button( -text => 'Test', -command => sub { print "Pushed\n" }, )->pack(); $mw->Button( -text => 'Quit', -command => sub { Tk::exit(0) }, )->pack(); my $I; while (1) { $mw->DoOneEvent( DONT_WAIT | ALL_EVENTS ); if ( ++$I > 10000 ) { #slows things down use 1 for max speed print '.'; $I = 0; } }
    So instead of calling MainLoop in the secondary scripts, you do
    sub manual_loop_control { $mw1->DoOneEvent( DONT_WAIT | ALL_EVENTS ); $mw2->DoOneEvent( DONT_WAIT | ALL_EVENTS ); $mw3->DoOneEvent( DONT_WAIT | ALL_EVENTS ); }
    in a timer in your main Tk script, like
    $mw->repeat(10, \&manual_loop_control);
    Using this method, you can even combine Gtk2 and Tk (any event loop script) and run them simultaneously.

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: MainLoop control
by zentara (Cardinal) on Dec 12, 2007 at 13:40 UTC
    Launch your other Tk programs with a fork and exec:
    # simplest way, but ignores error handing my $pid; if($pid = fork() == 0) { exec("other_tk_script"); }
    Also, you can store those $pids in the main Tk script, so you can kill -9 them, if they hang, or you want to close them all together simultaneously.

    Here is a preferred syntax

    #!/usr/bin/perl my $kidpid; if ( !defined( $kidpid = fork() ) ) { #fork returned undef, so failed die "Cannot fork: $!"; } elsif ( $kidpid == 0 ) { # fork returned 0, so this branch is child exec("xterm -e top"); # if exec fails, fall through to the next statement die "can't exec : $!"; } else { # fork returned 0 nor undef # so this branch is parent sleep(5); my $result = kill "TERM", $kidpid; print "Killed child process $kidpid (result $result)\n"; sleep(5); }

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: MainLoop control
by Erez (Priest) on Dec 12, 2007 at 09:00 UTC
Re: MainLoop control
by Anonymous Monk on Dec 12, 2007 at 07:36 UTC
    launch a separate process for each mainloop