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:
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...
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
The value wxHORIZONTAL
is undefined because you haven't imported it from Wx
, so you are passing a value of zero to Wx::BoxSizer->new
without any warning being raised
You have used a value of zero for the third parameter to $frameSizer->Add
, which prevents the panel from expanding transversly to the direction of the sizer. You need wxEXPAND
in there to enable it, and you will also need to import the value of that constant of course
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