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

Hi Monks,
Please have a look in the code below.
I'm trying to have a scrollable table with fixed headers.Each cell of the table is a canvas, whose size may vary. This is a reduced version, containing only fixed size canvases with no items on them.
I expect that if the canvases are too high, the scrollbar on the right side will be activated. But if I enlarge the height of the canvases (change $graph_height to 800), they disappear...
Please advise!
#!/usr/bin/perl -w use strict; use warnings; use Tk; use Tk::Table; my $graph_width=300; my $graph_height=700; #my $graph_height=800; my $title_c; my $group; my $canvas; my $table; my @group_names=('A','B'); my $col=0; my $graph_win = MainWindow->new( ); $graph_win->withdraw; $table= $graph_win->Table( -rows => 2, -columns => 2, -scrollbars => 'e', -fixedrows => 1, -fixedcolumns => 0 )->pack( -expand => 1, -fill => 'both', ); foreach $group (@group_names){ $title_c=$table->Label( -text => $group, -relief => 'groove', -font => "{Arial} 15 bold", -borderwidth => 2, ); $table->put(0,$col, $title_c); $col++; } $col=0; foreach $group (@group_names){ $canvas = $table->Scrolled("Canvas", -scrollbars => 's', -width => 300, -height => $graph_height, -background => 'white', -borderwidth => 2, -relief => 'groove', -scrollregion => [0,0,$graph_width,$graph_height] ); $table->put(1,$col++, $canvas); } $graph_win->deiconify(); $graph_win->raise(); $graph_win->geometry('1000x800+10+10'); MainLoop;

Replies are listed 'Best First'.
Re: Problem with scrolling Tk Table
by zentara (Cardinal) on Apr 25, 2007 at 13:19 UTC
    Hi, this is a pretty tricky one, because the scrolled Table acts weird to begin with, and you are trying to pack Scrolled Canvases into it's cells. I can only offer you are clue, because I believe it will take some experimenting to get it to work like you expect.

    Put the Table (non-scrolled) into a Scrolled Pane. That will keep things visible. I don't know what your variable cell sizes will do in this setup, you may have to do some fancy callbacks, like reconfiguring the canvases' scrollregions after a mainwindow resize. Anyways..... think Scrolled Pane.

    #!/usr/bin/perl -w use strict; use warnings; use Tk; use Tk::Table; require Tk::Pane; my $graph_width=300; my $graph_height=400; #my $graph_height=800; my $title_c; my $group; my $canvas; my $table; my @group_names=('A','B'); my $col=0; my $graph_win = MainWindow->new( ); $graph_win->withdraw; my $pane = $graph_win->Scrolled('Pane')->pack(-expand=>1,-fill=>'both' +); $table= $pane->Table( -rows => 2, -columns => 2, -scrollbars => 'e', -fixedrows => 1, -fixedcolumns => 0 )->pack( -expand => 1, -fill => 'both', ); foreach $group (@group_names){ $title_c=$table->Label( -text => $group, -relief => 'groove', -font => "{Arial} 15 bold", -borderwidth => 2, ); $table->put(0,$col, $title_c); $col++; } $col=0; foreach $group (@group_names){ $canvas = $table->Scrolled("Canvas", -scrollbars => 's', -width => 300, -height => $graph_height, -background => 'white', -borderwidth => 2, -relief => 'groove', -scrollregion => [0,0,$graph_width,$graph_height] ); $table->put(1,$col++, $canvas); } $graph_win->deiconify(); $graph_win->raise(); $graph_win->geometry('600x500+30+30'); MainLoop;

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      Thanks,
      This was my original implementation but it lacks one important feature of the Table which is keeping the header row visible regardless of the scrolling.
      A possible work around is to pack another frame on top of the pane which will hold the headers.
      But then it's quite hard to deal with maintaining the widths of the headings and the table cells the same.
        I'm not sure what you are trying to do, but maybe you are overcomplicating it by trying to use a Table. This was posted a few months ago by rcseege. Just add some header canvases.
        #!/usr/bin/perl use strict; use Tk; use Tk::Pane; # by rcseege my $mw = MainWindow->new; my $sPane = $mw->Scrolled("Pane", -scrollbars => 'se', -sticky => 'nsew', -bg => 'black', -width => 300, -height => 300 )->pack(qw/-expand 1 -fill both/); my $container = $sPane->Subwidget('scrolled'); foreach my $row (0 .. 3) { foreach my $col (0 .. 3) { createTile($container, $row, $col); } } foreach my $i (0 .. 3) { $container->gridRowconfigure($i, -weight => 1); $container->gridColumnconfigure($i, -weight => 1); } MainLoop; ## Each 'Tile' is a Frame containing a Scrolled Canvas + ## another Frame containing zoom controls. sub createTile { my ($parent, $x, $y) = @_; my $tileColor = "black"; my $tile = $parent->Frame(-bg => $tileColor)->grid( -padx => 5, -pady => 5, -row => $x, -column => $y, -sticky => 'nsew' ); my $sc = $tile->Scrolled('Canvas', -scrollbars => 'osoe', -scrollregion => [0, 0, 200, 200], -width => 125, -height => 125, -background => randColor() )->pack(qw/-fill both -side top -expand 1/); my $count = int(rand(6)) + 2; foreach my $i (1 .. $count) { my ($x, $y) = (randNumber(), randNumber()); my $size = randNumber(); $sc->createRectangle($x, $y, $x+$size, $y+$size, -fill => randColor(), -outline => 'black', -width => 2 ); } my $bFrame = $tile->Frame(-bg => $tileColor)->pack(qw/-side top/); $bFrame->Button( -text => " Zoom Out ", -command => sub { $sc->scale(qw/all 0 0 .5 .5/); } )->pack(qw/-side left -padx 5/); $bFrame->Button( -text => " Zoom In", -command => sub { $sc->scale(qw/all 0 0 2 2/); } )->pack(qw/-side right -padx 5/); } sub randColor { my @colors = qw(red yellow blue orange green purple); return $colors[rand($#colors + 1)]; } sub randNumber { my ($max, $min) = (100, 10); my $size = int(rand($max)); $size += $min if $size < $min; return $size; }

        I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Problem with scrolling Tk Table
by mikasue (Friar) on Apr 25, 2007 at 13:41 UTC

    I agree!

    At first I was going to suggest redrawing the table upon a resize but this idea is much better. Remove the scrollbars from the canvas and scroll the entire pane.

    Thanks zentara, I learned something also.