2009-06-03 6 views
2

Le code suivant produit à peu près ce que je veux, mais le volet déroulant sur la gauche ne défile pas. J'utilise ActivePerl 5.8.9 construire 825:Pourquoi mon Perl/Tk Scrolled ne défile-t-il pas?

Le code est:

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; 
} 

J'espère que quelqu'un peut signaler la chose mineure que j'ai manqué de cette fin et ma frustration.

+0

Glen, lorsque vous utilisez strict, vous devez déclarer vos variables avant de les utiliser. mon $ foo = 'bar'; Ou dans votre exemple ci-dessous, mes boutons $; $ boutons -> {$ box} = $ parent-> Bouton (-text => $ box) -> pack (-pady => 10); – daotoad

Répondre

2

Quelques remarques d'abord: Votre code n'est pas strict, ce qui rend le débogage plus difficile. Vous n'appelez pas non plus pack sur l'un de vos widgets. Vous ne devez pas utiliser une perluète avant le sous-nom lorsque vous invoquez des sous-marins, à moins que vous ne connaissiez ses effets et que vous en ayez besoin - voir perldoc perlsub pour plus de détails.

Les largeurs des trois panneaux totalisent plus de 800. La disposition que vous voulez n'est pas si claire.

Maintenant, voici un code (stolen from PerlMongers) qui crée un volet déroulant avec un tas de boutons:

#!/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; 
+0

Il utilise le gestionnaire de géométrie 'place' au lieu de 'pack' (ou 'grid'). –

+0

Je n'utilise pas Tk donc je ne m'en suis pas rendu compte. Je vous remercie de le faire remarquer. –

3

Vous avez deux problèmes. La première est que vous devriez utiliser le widget Pane directement plutôt que de créer un autre Frame à l'intérieur. L'autre problème semble être l'utilisation du gestionnaire de géométrie place dans un widget Pane. Essayez plutôt d'utiliser pack.

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

Avec cela de la manière, s'il vous plaît apprendre à utiliser les strict et warnings pragma. Ils sont inestimables pour vous aider à écrire du bon code. Comme l'a souligné Sinan, n'utilisez pas la notation &foo() pour invoquer des sous-programmes. C'est la syntaxe (très) ancienne. Ce n'est pas nécessaire et est potentiellement dangereux. Enfin, je recommande d'utiliser pack ou grid plutôt que place pour Perl/Tk. Il est généralement plus facile d'obtenir le comportement que vous voulez. Utilisez uniquement place lorsque vous avez besoin d'un positionnement absolu. Vous pouvez même mélanger et associer des gestionnaires de géométrie tant qu'ils gèrent des cadres différents.

+0

merci beaucoup pour votre aide J'ai pris à bord tous vos commentaires et le "-> pack (-pady => 10)" a travaillé un régal. mon nouveau problème est que l'utilisation stricte et les avertissements a signifié que la ligne $ boutons -> {$ box} = $ parent-> Button (-text => $ box) -> pack (-pady => 10) ; renvoie l'erreur suivante: « symbole mondial "boutons $" exige le nom du paquet explicite dans C: \ temp \ LH App moniteur ligne \ TestScrollee.pl 54. d'exécution de C: \ temp \ LH App Monitor \ TestScrollee. pl interrompu en raison d'erreurs de compilation. " pourquoi est-ce que j'ai compris pour hash le $ était correct pour accéder à un élément du hachage défini avec% – Glen

+2

Le pragma strict vous oblige à déclarer vos variables avant leur utilisation ou les qualifier complètement (dans le cas de vars de paquet) . Vous avez besoin d'un "mes boutons $" avant de l'utiliser. C'est un peu d'effort supplémentaire, mais aide à améliorer votre code. par exemple.vous pouvez plus facilement identifier les erreurs comme l'utilisation de "$ tmp" au lieu de "$ temp" et utiliser le même nom dans différentes parties du programme sans crainte de collision. –