perlfillexpandwxperl

wxPerl: add component which resizes automatically when parent frame gets resized


I am relatively new to Perl and I am using wxPerl to create a GUI application. Now, I want to add a Panel into a Frame, possibly using a sizer so that the panel resizes automatically as the frame gets resized.

So here's what I got:

(1) I have to use a BoxSizer, which stretch components in one direction.

(2) I have to pass parameters in the Add subroutines to stretch components in another direction.

I wrote the following code:

package Main;
use Wx;
use parent 'Wx::App';

sub OnInit {
    my $frame = Wx::Frame->new(undef, -1, "SimpleCalc ".$Information::VERSION_NO, [-1,-1], [-1,-1]);
    my $centerPanel = Wx::Panel->new($frame, -1, [-1,-1], [-1,-1]);
    #set red background
    $centerPanel->SetBackgroundColour(Wx::Colour->new(255,0,0));
    my $frameSizer = Wx::BoxSizer->new(wxHORIZONTAL);
    $frameSizer->Add($centerPanel, 1, 0, 0);
    $frame->SetSizer($frameSizer);
    $frame->Center();
    $frame->Show(1);
    return 1;
}

my $app = Main->new;
$app->MainLoop;

The unwanted result:

unstretched

What I want is to stretch the red panel in both (horizontal and vertical) direction, or in short, I want something similar to BorderLayout in Java.

According to some online tutorials, I tried to replace $frameSizer->Add($centerPanel, 1, 0, 0); with $frameSizer->Add($centerPanel, 1, wxEXPAND, 0);, but the script doesn't run. An error occurs saying that it is unable to resolve overload for Wx::Sizer::Add(Wx::Panel, number, scalar, number). I also tried $frameSizer->Add($centerPanel, 1, 0, 0, wxEXPAND);, but the frame obtained is exactly the same as the frame in the image.

Is it possible to have something similar to Java's BorderLayout in wxPerl? Thanks in advance.

P.S. I know there is a duplicate, but there are no concrete answers...


Solution

  • Update

    In case you weren't aware, the default sizer for any child window will make it fill its available space, so to achieve the effect you're asking for all you need is this

    use strict;
    use warnings;
    
    package Information;
    
    our $VERSION_NO = 9.99;
    
    
    package Main;
    use Wx qw/ :colour /;
    use parent 'Wx::App';
    
    sub OnInit {
    
      my $frame = Wx::Frame->new(undef, -1, "SimpleCalc $Information::VERSION_NO");
    
      my $centerPanel = Wx::Panel->new($frame);
      $centerPanel->SetBackgroundColour(wxRED);
    
      $frame->Center;
      $frame->Show;
    
      return 1;
    }
    
    my $app = Main->new;
    $app->MainLoop;
    

    Original

    It would have helped you a lot if you had use strict and use warnings in place! I and several others have to endlessly encourage people to do that but it seems sometimes that the message will never get across. Please try to make a habit of adding these statements to the top of every Perl program you write, and help us to spread the word

    There are two things preventing your program from working

    Here's a rewrite of your code that fixes these problems, and also takes advantage of the defaults that will be used for missing parameters. I've also used wxRED instead of creating a new Wx::Colour object. I had to set a value for $Information::VERSION_NO too

    This code works as you expected

    use strict;
    use warnings;
    
    package Information;
    
    our $VERSION_NO = 9.99;
    
    
    package Main;
    
    use Wx qw/ :sizer :colour /;
    use parent 'Wx::App';
    
    sub OnInit {
        my $frame = Wx::Frame->new(undef, -1, "SimpleCalc $Information::VERSION_NO");
    
        my $centerPanel = Wx::Panel->new($frame);
        $centerPanel->SetBackgroundColour(wxRED);
    
        my $frameSizer = Wx::BoxSizer->new(wxHORIZONTAL);
        $frameSizer->Add($centerPanel, 1, wxEXPAND);
        $frame->SetSizer($frameSizer);
    
        $frame->Center;
        $frame->Show;
    
        return 1;
    }
    
    my $app = Main->new;
    $app->MainLoop;
    

    output

    Fixed WxWidgets screen http://bit.ly/1JNrrEL