Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

returning values from Perl-Tk events

by thunders (Priest)
on Mar 26, 2002 at 20:34 UTC ( #154506=perlquestion: print w/replies, xml ) Need Help??
thunders has asked for the wisdom of the Perl Monks concerning the following question:

Hello fellow Monks,

I've been working with Tk for a few days now and I've run into something I can't get my brain around. How can I return or pass a value from a button event?

I'm writing an application that will let me compare photographs from a directory two at a time until I've decided on a favorite. The problem comes with trying to achieve this using Tk Buttons.

I've tried several different methods, but I still cant figure how to pass an array or return it through a button event subroutine, so that my array will eventually shrink as I make choices.

Any suggestions?

#!/usr/bin/perl -w use Tk; chdir('images'); my @image_files = <*.gif>; #initialize Main Window my $mw = MainWindow->new; #eventually I want to have this part continue until only one image rem +ains while (scalar @image_files > 1){ my $pic1 = shift @image_files; my $pic2 = shift @image_files; @image_files = show_two_buttons($mw, $pic1,$pic2,\@image_files); } #do something when we have one picture left. #dosomething(); MainLoop; sub show_two_buttons{ my $mw = shift @_; for ($mw->packSlaves()){ $_->destroy() if Tk::Exists($_); #clear out window } my $first_pic = shift @_; my $second_pic = shift @_; my @image_files = @{shift @_}; #generate two buttons for $file($first_pic,$second_pic){ my $image = $mw->Photo(-file=>$file); #cant figure how to return or pass arrays on the command here $mw->Button( -image=>$image, -text=> $file, -command=>[\&return_array, $file, \@image_files] )->pack(-side=>"left"); } return @image_files;#array never changes } sub return_array{ my $file = shift @_; my @image_files = @{shift @_}; push @image_files, $file; print @image_files; #only contains one file return @image_files;#doesn't return to anything }

Replies are listed 'Best First'.
Re: returning values from Perl-Tk events
by {NULE} (Hermit) on Mar 26, 2002 at 23:16 UTC
    Hi thunders,

    Your issues aren't so much related to passing that array around. Your main problem here is that you are trying to use functional code in an event driven framework. The @image_files array is already paired down to one element before any widgets are drawn because Tk doesn't render anything until you call MainLoop. This means your code for pairing down the images has to happen somewhere else, like in your return array function.

    But before you go re-engineering your code to meet that requirement let me talk about returning your array. Don't do it! You are already passing a reference to the array so when your subroutine returns it has alread been modified. You'll see in my sample code that I don't return *anything* because I don't have to. I also clearly labled my reference, which IMO is a good coding practice.

    My guess is that you haven't worked that much with event driven programming. I hadn't myself until I started playing a lot with Tk. I think you are on the right track, but there are probably easier (though more long winded) ways to approach what this accomplishes. I think this technique you are using is a neat hack. In either case I hope this helps you.

    #!/usr/bin/perl -w use strict; use Tk; chdir('images'); my @image_files = <*.gif>; #initialize Main Window my $mw = MainWindow->new; show_two_buttons($mw,\@image_files); MainLoop; exit; # Subroutines # sub show_two_buttons{ my $mw = shift; for ($mw->packSlaves()){ $_->destroy() if Tk::Exists($_); #clear out window } my $image_file_REF = shift; my $first_pic = shift @{$image_file_REF}; my $second_pic = shift @{$image_file_REF}; #generate two buttons for my $file ($first_pic,$second_pic){ my $image = $mw->Photo(-file=>$file); $mw->Button( -image=>$image, -text=> $file, -command=>[\&return_array, $mw, $file, $image_file_REF] )->pack(-side=>"left"); } } sub return_array{ my $mw = shift; my $file = shift; my $image_file_REF = shift; push @{$image_file_REF}, $file; # Uncomment to show what's left. #print join ", ", @{$image_file_REF}; #print "\n"; # Here is where we do our test to see what is left if (scalar @{$image_file_REF} > 1) { show_two_buttons($mw, $image_file_REF); } else { print "All done!\n"; exit; } }
      My guess is that you haven't worked that much with event driven programming

      Good Guess.

      I've had Learning Tk for a while. I've written a few dozen GUI apps with it, and I've done VB, but The event driven model was mostly transparent to me until I tried something like this.

      Thank you so much for the code and advice.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://154506]
Approved by root
[james28909]: ok i have a new question ;)
[james28909]: i am not sure how to ask google this either
[james28909]: i am getting the current time on my machine with scalar localtime;
[james28909]: i am scraping a website and retrieving a date stamp of an article.
[james28909]: well time/data stamp of the article
[stevieb]: james28909: what's the problem/question?
[james28909]: it is not an absolute date like "27" or "31". sometimes it is like wednesday or friday
[james28909]: and i need to format those special instances into an absolute date instead of "yesterday"
[stevieb]: ask a question on SoPW, and include at least a half-dozen examples of the input, and at least one example of expected output

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2017-04-29 02:34 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (531 votes). Check out past polls.