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

I spent multiple hours last night attempting to figure out just precisely how scrollbars work...I've read the documentation that comes with Tk along with looking at some books and I can't get a scrollbar to work with a fixed-size Canvas. I seem to be missing something...here are some examples of the code I've tried(This list is relatively long):

# $main is MainWindow my $canvas = $main->Scrolled('Canvas', -scrollbars => 'e', -height => 200, -width => 200, )->pack; $canvas->packPropagate(0);
Running this code produces a very thin window with no contents. Adding
-scrollregion => [0,0,200,200],
to the arguments given to Scrolled produces the same output.
Going about things in a slightly different way produces a window of the correct size:
my $frame = $main->Scrolled('Canvas', -scrollbars => 'e', )->pack; my $canvas = $frame->Subwidget('canvas'); $canvas->configure(-height => 200, -width => 200); $canvas->packPropagate(0);
Yet, when I insert some widgets, and just to test it lets add in
foreach (1..20) { $canvas(or $frame)->Label(-text => 'test')->pack; }
the contents of the canvas obviously exceed its specified height yet the scrollbar doesn't let me scroll up/down. Adding -scrollregion => [0,0,200,200] to the arguments given to configure affects nothing.

In a final attempt to get a scrollbar to work with my canvas, I tried using the Scrollbar method:
my $canvas = $main->Canvas(-height => 200, -width => 200, )->pack(-side => 'left'); $canvas->packPropagate(0); my $scrollbar = $main->Scrollbar( -orient => 'vertical', -command => ['yview' => $canvas], )->pack(-fill => 'y', -side => 'right');
Clicking on the scrollbar yields a slew of error messages. I've tried a few different lists in the -command option including
['yview', $canvas, 'scroll', 1, 'units']
and to no avail. Any help here would be appreciated. I am assuming that I am missing something that is very simple here, possibly a need to inform the Canvas of the Scrollbar or something. I've looked online yet can only find examples of Scrollbars used with Listboxes, thus not helping me here. Thank you,
-Eric

Replies are listed 'Best First'.
Re: A Canvas and a Scrollbar with Tk
by The Mad Hatter (Priest) on Dec 12, 2003 at 02:45 UTC
    You might want to take a look at TK Scrollbars not working correctly and the replies; I think your question has been answered there. (BTW, I found that node via Super Search (for "tk scrollbar canvas" in text and titles)).

    (And welcome to PM, Eric. ; )

Re: A Canvas and a Scrollbar with Tk
by JamesNC (Chaplain) on Dec 12, 2003 at 13:00 UTC
    An Example:
    use Tk; use Tk::Canvas; use Tk::Label; my $mw = tkinit(-title, 'Canvas'); #$mw->geometry('250x250'); my $frame = $mw->Frame(-width, 250, -height, 250)->pack(-fill, 'both', + -expand,1); my $canvas = $frame->Scrolled('Canvas', -width, 600, -height, 600, -scrollbars, 'osoe' )->pack(-fill,'both',-expand,1); my $btn = $mw->Button(-text, "Add Stuff", -command,\&addStuff) ->pack(); MainLoop; sub addStuff{ $canvas->createText(500, 500, -text, "Some text @ 500, 500." ); $canvas->createRectangle( 50, 50, 110, 110, -fill, 'red'); $canvas->createRectangle( 150, 150, 210, 210, -fill, 'green'); $canvas->createRectangle( 250, 250, 310, 310, -fill, 'blue'); $canvas->createText(20, 20, -text, "Some text @ 20, 20." ); # # Your can use an array for your bounding box # commented out to show both ways to set the scrollregion # Just make sure you are 1 less on lower right and bottom # Or you will have out of bounds array... easy to forget # if you don't use a frame with your canvas #$canvas->configure(-scrollregion => [ 0, 0, 599, 599]); $canvas->configure(-scrollregion => [$canvas->bbox('all')]); }

    Update: commented out initial geometry
    JamesNC
Re: A Canvas and a Scrollbar with Tk
by pg (Canon) on Dec 12, 2003 at 17:02 UTC

    First let me answer your immediate question thru a piece of simple demo code:

    use Tk; use strict; use warnings; my $main = new MainWindow(); my $canvas = $main->Scrolled('Canvas', -scrollbars => 'se', -height => 400, -width => 400, )->pack; $canvas->createOval(100,100,500,500); MainLoop;

    The code has been tested and the scrollbar worked. The demo code simply creates a canvas (which can be imagined as a “window”, through which you can peek into the world), then draws an oval that exceeds the canvas (so part of the oval is beyond the “window”), now you use the scrollbars to move the “window” and peek at different portions of the oval.

    Now the answer to a question you didn’t ask. You tried to add Labels on top of canvas, and that is not the best practice for GUI programming. It is not only true to Perl/Tk, but any GUI platform: Canvas is not used to hold other GUI components, but only drawing (including text). I saw that you tried to add Label on canvas, and that is discouraged. To add text on canvas, use:

    $canvas->createText(…);
Re: A Canvas and a Scrollbar with Tk
by Silverstrike (Novice) on Dec 12, 2003 at 19:55 UTC
    Thank you all! I guess I never realized it before, but now that I think about it, canvas is mainly for drawing and not holding other widgets...
    -Eric