suggest a better method. If it was me, I would put the varying number grid on a Tk::Canvas, and just use tags to control which table is currently showing. It is a very good way to do it. As to your method of recreating multiple tables,
the following is probably somewhat along the way to do it. You have a packing problem, because the window will want to resize with each table. Maybe you can work that out.
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
use Tk::Table;
my $mw = MainWindow->new();
my $upper = $mw->Frame()->pack(-side => 'top');
my $but1 = $upper->Frame()->pack();
my $lower = $mw->Frame()->pack(-side => 'bottom');
my $table = $lower->Table()->pack;
my $new_row = int rand 4;
my $new_col = int rand 5;
upd_table($new_row,$new_col);
$but1->Button(
-text => 'update',
-command => sub {
$new_row = int rand 4;
$new_col = int rand 5;
upd_table( $new_row,$new_col) },
)->pack();
MainLoop();
exit;
sub upd_table {
$table->packForget();
my ($rowin,$colin) = @_;
$table = $lower->Table(-rows => $rowin, -columns => $colin)->pack;
foreach my $row ( 0 .. $rowin-1 ) {
foreach my $col ( 0 .. $colin ) {
my $x = int rand 10;
my $cell = $table->Entry( -width => 4, -text => $x );
$table->put( $row, $col, $cell );
}
}
}
as far as making a Canvas do it, look at this.
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
#by thundergnat on comp.lang.perl.tk
my $top = MainWindow->new;
my $canvas = $top->Canvas->pack(-expand => 1, -fill => 'both');
my (@dots, @lines);
my ($gridx, $gridy) = (5, 6);
for my $y(0 .. $gridx-1){
for my $x(0 .. $gridy-1){
$dots[$x][$y] = $canvas->createOval(
25 + $x * 55,
25 + $y * 55,
35 + $x * 55,
35 + $y * 55,
-fill => 'red'
);
}
}
current($dots[0][0]);
$top->bind('<Up>' => sub{
my ($point, $x, $y) = get_coords('active');
return if ($point < $gridy);
draw($dots[$x][$y], $dots[$x][$y-1]);
}
);
$top->bind('<Down>' => sub{
my ($point, $x, $y) = get_coords('active');
return if ($point > $gridy * ($gridx - 1));
draw($dots[$x][$y], $dots[$x][$y+1]);
}
);
$top->bind('<Left>' => sub{
my ($point, $x, $y) = get_coords('active');
return if ($point % $gridy == 1);
draw($dots[$x][$y], $dots[$x-1][$y]);
}
);
$top->bind('<Right>' => sub{
my ($point, $x, $y) = get_coords('active');
return unless ($point % $gridy);
draw($dots[$x][$y], $dots[$x+1][$y]);
}
);
$top->bind('<1>' => sub{
my (undef, $x1, $y1) = get_coords('active');
my (undef, $x2, $y2) = get_coords('current');
return unless defined $x2;
draw($dots[$x1][$y1], $dots[$x2][$y2]);
}
);
$top->bind('<BackSpace>' => sub{
return unless @lines;
my ($line, $start) = @{$lines[-1]};
$canvas->delete($line);
current($start);
pop @lines;
}
);
MainLoop;
sub get_coords{
my $tag = shift;
my $item = $canvas->find(withtag => $tag);
return unless $item;
return $item->[0], ($item->[0] - 1) % $gridy, int (($item->[0] - 1) /
+$gridy);
}
sub current{
$canvas->itemconfigure('active', -fill => 'red');
$canvas->itemconfigure($_[0], -fill => 'yellow');
$canvas->dtag('active', 'active');
$canvas->addtag('active', 'withtag', $_[0]);
}
sub draw{
my ($start, $end) = @_;
my @start_coords = $canvas->bbox($start);
my @end_coords = $canvas->bbox($end);
return unless @end_coords;
my @line_coords = (
($start_coords[0] + $start_coords[2]) / 2,
($start_coords[1] + $start_coords[3]) / 2,
($end_coords[0] + $end_coords[2]) / 2,
($end_coords[1] + $end_coords[3]) / 2
);
my $line = $canvas->createLine(@line_coords, -arrow => 'last');
push @lines, [$line, $start];
current($end);
}
__END__
|