tags:

views:

854

answers:

2

Hi All,

The following code produces pretty much what I want, but the scrollable pane on the left doesn't scroll. I am using ActivePerl 5.8.9 Build 825:

The code is:

use Tk;
use Tk::Pane;
use Tk::LabFrame;

# create the application window
my $MW = MainWindow->new ( -background => "GREY" );

# set the x/y size for the window
$MW->geometry("800x600");

# add a window title
$MW->title("Monitor Boxes");

# Disallow window resizing
$MW->resizable(0,0);

# create a labelled frame on the window to house the list of buttons to be pressed
$boxListFrame = &create_framed_section( "List Of Boxes", 
        "acrosstop", 
        5, 
        5, 
        170, 
        565,
        "BLUE", 
        "GREY");

# create a labelled frame on the window to house the information to be displayed 
# when a particular button is pressed
$statusOfBoxFrame = &create_framed_section( "Status", 
         "acrosstop", 
         185, 
         5, 
         600, 
         565, 
         "BLUE", 
         "GREY");

# create a scrollable pane in the left hand pane so that if more buttons than 
# is able to be displayed are put onto the application the scroll bar will allow 
# the ones not displayed to be access
my $pane = $MW->Scrolled(   'Pane', 
       -scrollbars => 'e', 
       -width => 140, 
       -height => 555, 
       -background => "GREY")->place(-x=>15,-y=>25);

# setup the array of buttons
@boxes = ("BUTTON1", "BUTTON2", "BUTTON3", "BUTTON4", "BUTTON5", "BUTTON6", "BUTTON7", "BUTTON8", "BUTTON9", "BUTTON10", "BUTTON11", "BUTTON12", "BUTTON13", "BUTTON14", "BUTTON15", "BUTTON16");

# put the buttons onto the scrollable pane in the frame on the window (LOL)
DisplayCheckButtons( $pane, @boxes);

# wait until the user exits the app
MainLoop;

# exit the app
exit 0;

sub DisplayCheckButtons 
{
    my ( $parent, @names ) = @_;
    $Frame->destroy if $Frame;
    $Frame = $parent->Frame( -width => 160, 
        -height => 555, 
        -background => "GREY")->place(-x=>15,-y=>15);

    $xpos = 5;
    $ypos = 5;

    foreach $box (@names)
    {
     $buttons->{$box} = $Frame->Button(-text => $box)->place(-x=>$xpos,-y=>$ypos);

     $ypos = $ypos + 40;

    }
}

sub create_framed_section
{
    # get the parameters
    my($label, $labelside, $posX, $posY, $width, $height, $fontColour, $backgroundColour) = @_;

    # create the item in the desired position with supplied information
    $frame = $MW->LabFrame( -label      => $label,
       -labelside  => $labelside,
       -width      => $width,
       -height     => $height,
       -foreground => $fontColour,
       -background => $backgroundColour,
       )->place(-x=>$posX,-y=>$posY);

    return $frame;
}

I hope that someone can point out the minor thing that I have missed from this and end my frustration.

Kind regards,

Glen

+2  A: 

A few observations first: Your code is not strict safe which makes debugging harder. You are also not calling pack on any of your widgets. You shouldn't use an ampersand before the sub name when invoking subs unless you know its effects and want them -- see perldoc perlsub for details.

The widths of the three panels add up to more than 800. The layout you want is not that clear.

Now, here is some code (stolen from PerlMongers) that creates a scrollable pane with a bunch of buttons:

#!/usr/bin/perl

use strict;
use warnings;

use Tk;
use Tk::Pane;

my $top = MainWindow->new;
$top->Label(-text => "Enter the scroll frame")->pack;

my $frame = $top->Scrolled(
    'Frame',
    -scrollbars => "e",
)->pack;

$frame->Button(-text => "BUTTON $_")->pack for ( 1 .. 16 );

MainLoop;
Sinan Ünür
He's using the 'place' geometry manager instead of 'pack' (or 'grid').
Michael Carman
I don't use Tk so I did not realize that. Thank you for pointing it out.
Sinan Ünür
+3  A: 

You have two problems. The first is that you should be using the Pane widget directly rather than creating another Frame inside it. The other problem appears to be with using the place geometry manager inside a Pane widget. Try using pack instead.

$buttons->{$box} = $parent->Button(-text => $box)->pack(-pady => 10);

With that out of the way, please learn about using the strict and warnings pragmas. They're invaluable in helping you to write good code. As Sinan pointed out, don't use the &foo() notation for invoking subroutines. That's the (very) old syntax. It isn't necessary and is potentially harmful. Finally, I'd recommend using pack or grid rather than place for Perl/Tk. It's generally easier to get the behavior you want. Only use place when you need absolute positioning. You can even mix-and-match geometry managers as long as they're managing different frames.

Michael Carman
thank you very much for your helpi have taken on board all of your comments and the "->pack(-pady => 10)" worked a treat.my new issue is that using strict and warnings has meant that the line$buttons->{$box} = $parent->Button(-text => $box)->pack(-pady => 10);returns the following error:"Global symbol "$buttons" requires explicit package name at C:\temp\LH Monitor App\TestScrollee.pl line 54.Execution of C:\temp\LH Monitor App\TestScrollee.pl aborted due to compilation errors."why is this as i understood for hashes the $ was correct to access an element of the hash defined with %
Glen
The strict pragma requires you to either declare your variables prior to use or fully qualify them (in the case of package vars). You need a "my $buttons" before using it. It's a little bit of extra effort but helps improve your code. e.g. you can more easily identify mistakes like using "$tmp" instead of "$temp" and use the same name in different parts of the program without fear of collision.
Michael Carman