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

Hello Monks

I am attempting to figure out how to select a new cell and deselect the previously selected cell when the new cell is selected and I am just not sure how to do it

I am testing with code I found on Active State's site

use Tk; use Tk::Table; my $mw = MainWindow->new; my $table = $mw->Table->pack; my $r; foreach $r (0..5) { my $c; foreach $c (0..5) { $table->put($r,$c,"$r,$c"); $table->get($r,$c)->bindtags([$table]); # messy } } $table->bind('<1>', sub { my ($w) = @_; my ($row,$col) = $table->Posn($w); print "row=$row, col=$col\n"; $w->configure(-background=>'grey'); }); MainLoop;

When this code is run on each cell that is clicked on (selected), the background is changed to grey. I would like to have it grey the new cell that is selected and change the previous selected cell back to white, ultimately deselecting the previous cell. The goal is to only have one cell selected at a time, not multiples

I don't seem to be able to come up with the necessary logic to do this. I tried adding a variable to save the row/column. Anyway, I would appreciate any words of wisdom, suggestions/examples etc, that you may have

Thank You

Replies are listed 'Best First'.
Re: Tk::Table cell select/deselect
by wjw (Priest) on Jun 09, 2014 at 19:18 UTC

    TableMatrix

    Maybe Table::Matrix::Spreadsheet? I didn't read it, but it sound about right. I saw on a google search that TableMatrix seems to have the functionality you are looking for from a cell selection point of view... Worth checking out, tho I may have mis-read...

    Hope that is helpful...

    ...the majority is always wrong, and always the last to know about it...

    Insanity: Doing the same thing over and over again and expecting different results...

    A solution is nothing more than a clearly stated problem...otherwise, the problem is not a problem, it is a facct

      Thank You for your reply. I have tried TableMatrix in the past, but it doesn't seem to work very well with Windows

Re: Tk::Table cell select/deselect
by Anonymous Monk on Jun 09, 2014 at 19:51 UTC

    One way

    #!/usr/bin/perl -- ## ## 2014-06-09-12:49:11 ## ## ## perltidy -olq -csc -csci=10 -cscl="sub : BEGIN END if " -otr -opr +-ce -nibc -i=4 -pt=0 "-nsak=*" #!/usr/bin/perl -- use strict; use warnings; use Tk; use Tk::Table; Main( @ARGV ); exit( 0 ); sub Santeria { my( $w ) = @_; #~ my( $w , $table ) = @_; my $table = $w->parent; $_->configure( -background => 'white' ) for $table->children; my( $row, $col ) = $table->Posn( $w ); print "row=$row, col=$col\n"; $w->configure( -background => 'grey' ); } ## end sub Santeria sub Main { my $mw = MainWindow->new; my $table = $mw->Table->pack; for my $iy ( 0 .. 5 ){ for my $ix ( 0 .. 5 ) { $table->put( $ix, $iy, "x($ix),y($iy)" ); } } #~ $table->bind( 'Tk::Label', '<1>', [ \&Santeria, $table ] ); $table->bind( 'Tk::Label', '<1>', \&Santeria ); #~ use Tk::WidgetDump; $mw->WidgetDump; MainLoop; } ## end sub Main __END__

    You could also iterate in other Tk::Table ways, maybe even on $table->{Rows}

    Another way, keep track of the selected widget, since it belongs to $table

    my $last = $table->{last_selected}; $last and $last->configure( -background => 'white' ); $w->configure( -background => 'grey' ); $table->{last_selected} = $w;

    I know what you're thinking, if you're going to do that, you should subclass Tk::Table, and add a destructor where you clean up these extra keys... :D

      Thank You, excellent solution, I appreciate it and wish I would have been able to get it there. I will be able to adapt either of your suggestions for my needs. Thanks again.

Re: Tk::Table cell select/deselect
by locked_user sundialsvc4 (Abbot) on Jun 09, 2014 at 19:55 UTC

    You are on the right track.   You need to save the selected row and column ... these initially being undef to indicate “no selection.”   When the user clicks on a cell, first check to see if a cell is already selected and if so, turn it white.   Then, remember the new selection (row and column), and turn it grey as you do now.   So, your logic is ultimately responsible for knowing what has been selected and for visually presenting all changes of color.

    In some cases, you might also need logic to ignore a cell-click if, for example, the program is in the process of doing something with the current selection.   If the program is “busy,” the subroutine should simply return without doing anything, so as not to disturb the current-selection state.

      Absolutely correct! I just kept getting lost in doing that for some reason. I appreciate the reply!