in reply to Perl Tk GUI locking

Here is a simple generic example to get you rolling. In the thread, I count to a number ( defaults to 5 ). All you need to do is put your Net::Ftp or LWP code into the thread instead. The test count thing is to show you the main Tk gui is not blocking while the thread runs. This threaded example needs a simple improvement to close the thread when exiting by the window manager's close button.... that should give you something to work out on your own. (By the way, unless you really need Net::Ftp, I suggest using LWP to get your files, since you can setup a progressmeter for big files. Search groups.google.com for "LWP Tk progress" )
#!/usr/bin/perl use warnings; use strict; use threads; use threads::shared; use Tk; use Tk::ActivityBar; require Tk::Dialog; # setup thread before any Tk code my $go; my $die; my $progress; my $data, share $go; share $progress; share $die; share $data; $go = 0; $progress = 0; $die = 0; $data = 5; # example value to stop search at my $thread = threads->new(\&do_work); my $mw = MainWindow->new(-background => 'gray50'); my $lframe = $mw->Frame( -background => 'gray50',-borderwidth=>10 ) ->pack(-side =>'left' ,-fill=>'y'); my $rframe = $mw->Frame( -background => 'gray50',-borderwidth=>10 ) ->pack(-side =>'right',-fill =>'both' ); my $activity = $lframe->ActivityBar()->pack(-side => 'top',-anchor => +'n'); my $button = $lframe->Button( -text => 'get_file', -background => 'lightgreen', -command => sub { &get_a_worker } )->pack( -side => 'top', -anchor => 'n', -fill=>'x', -pady +=> 20 ); my $text = $rframe->Scrolled("Text", -scrollbars => 'ose', -background => 'black', -foreground => 'lightskyblue', )->pack(-side =>'top', -anchor =>'n'); my $repeat; my $startbut; my $repeaton = 0; $startbut = $lframe->Button( -text => 'Start Test Count', -background => 'hotpink', -command => sub { my $count = 0; $startbut->configure( -state => 'disabled' ); $repeat = $mw->repeat( 100, sub { $count++; $text->insert( 'end', "$count\n" ); $text->see('end'); } ); $repeaton = 1; })->pack( -side => 'top', -fill=>'x', -pady => 20); my $stoptbut = $lframe->Button( -text => 'Stop Count', -command => sub { $repeat->cancel; $repeaton = 0; $startbut->configure( -state => 'normal' ); })->pack( -side => 'top',-anchor => 'n', -fill=>'x', -pady => 20 ) +; my $exitbut = $lframe->Button( -text => 'Exit', -command => sub { $die = 1; $thread->join; if ($repeaton) { $repeat->cancel } exit; })->pack( -side => 'top',-anchor => 'n', -fill=>'x', -pady => 20 + ); #dialog to get file url--------------------- my $dialog = $mw->Dialog( -background => 'lightyellow', -title => 'Get File', -buttons => [ "OK", "Cancel" ] ); my $hostl = $dialog->add( 'Label', -text => 'Enter File Url', -background => 'lightyellow' )->pack(); my $hostd = $dialog->add( 'Entry', -width => 100, -textvariable => '', -background => 'white' )->pack(); $dialog->bind( '<Any-Enter>' => sub { $hostd->Tk::focus } ); my $message = $mw->Dialog( -background => 'lightyellow', -title => 'ERROR', -buttons => [ "OK" ] ); my $messagel = $message->add( 'Label', -text => ' ', -background => 'hotpink' )->pack(); $mw->MainLoop; ####################################### sub get_a_worker { #disable multiple thread starts $button->configure(-state =>'disabled'); # here you can pass data to the thread thru a shared var, # like what value to search for # $data = 5; # simple example $hostd->configure( -textvariable => \$data); if ( $dialog->Show() eq 'Cancel' ) { return } $activity->startActivity(); $go = 1; # start a repeater to watch shared vars my $watcher; $watcher = $mw->repeat(10, sub{ if ($go == 0){ $activity->configure(-value => 0); if ($progress == $data){ $text->insert( 'end', "\t\t\t$progress\n" ); $text->see('end'); } $watcher->cancel; $button->configure(-state=>'normal'); } }); } ################################## sub do_work{ $|++; while(1){ if($die == 1){ goto END }; if ( $go == 1 ){ #do your hash search or whatever foreach my $num (1..100){ $progress = $num; print "\t$num\n"; if( $num == $data ){ $go = 0 } select(undef,undef,undef, .5); if($go == 0){last} if($die == 1){ goto END }; } $go = 0; #turn off self before returning }else { select (undef,undef,undef,.1 ); } #nap time } END: } ###############################################

I'm not really a human, but I play one on earth. Cogito ergo sum a bum

Replies are listed 'Best First'.
Re^2: Perl Tk GUI locking
by banango (Initiate) on Jun 05, 2007 at 14:19 UTC
    Awesome, thank you so much for the sample code! I should be able to accomplish what I need with this as a resource. thanks!