Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
Syntactic Confectionery Delight
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??

I'm looking to have this added to the Wx Tutorials already on the site. Please feel free to comment and I'll make needed changes.

I'm following the development of Parde, a perl IDE written in perl.

With this, I'm toying with a few ideas and to actually get started I've been learning Wx, the GUI tool kit Padre uses.

I've found a couple of introductory articles that get you started.

They give you enough to create a basic Frame, a Panel, then a Text Box and a Button or two.

This is fine, but not a mention of how to manage the layout on the interface.

What's missing in these introductions is mention of the layout managers, at the least if they get mentioned you can at least google for them.

Layout managers manage it much simpler to position your widgets on the GUI.

These layout managers are BoxSizer, GridSizer and GridBagSizer.

I'm only going to cover the use of the BoxSizer for now, as this is the one that allows the simplest layout and the one I've only recently got my head around.

To start with we'll create a class that will create the main frame with a couple of widgets using the BoxSizer layout manager.

To start with:

package SizerExampleFrame; use strict; use warnings; use Wx qw /:everything/; use Wx::Event qw/EVT_BUTTON/; use base 'Wx::Frame'; sub new { my $class = shift; my $self = $class->SUPER::new( undef, -1, 'SizerExampleFrame', [-1,-1], [600, 400], );

Basically if you've started with any of the introductory articles you'll see that we've created a new Frame that is 600 by 400 pixels with a Title 'SizerExampleFrame'.

For this example we'll do something arbitrary, we'll create a Frame that has 4 "rows", we'll put labels in each of the rows, and in the last "row" we'll put in some buttons.

This will show how to use the BoxSizer with the two orientations to create a reasonably complex layout.

my $vbox = Wx::BoxSizer->new( wxVERTICAL );

To start with, we'll create a $vbox to hold the "rows". wxVERTICAL is a constant that tells the BoxSizer which orientation the Sizer is to take.

We'll create some panels to put widgets on:

my $pnl1 = Wx::Panel->new($self, -1); my $pnl2 = Wx::Panel->new($self, -1); my $pnl3 = Wx::Panel->new($self, -1); my $pnl4 = Wx::Panel->new($self, -1);

Now we have 4 Panels, each Parent is $self, being the frame we created right at the start.

With the Panels, we'll just stick a label in them.

my $lbl1 = Wx::StaticText->new( $pnl1, # parent -1, # id, "Testing: 1", # label [5,10], # position );

Just do this 2 more times:

my $lbl2 = Wx::StaticText->new( $pnl2, # parent -1, # id, "Testing: 2", # label [5,10], # position ); my $lbl3 = Wx::StaticText->new( $pnl3, # parent -1, # id, "Testing: 3", # label [5,10], # position );

For the 4th Panel we'll create a BoxSizer that runs vertically:

# now we want to create a vbox for the 4th panel # in this we will put button and other panels my $pnl4Vbox = Wx::BoxSizer->new( wxVERTICAL );

and another horizontally to hold the buttons:

my $btnBox = Wx::BoxSizer->new( wxHORIZONTAL ); my $pnlBtns = Wx::Panel->new( $pnl4, #parent -1, # id [-1,-1], # position [-1,-1], # size 0 # border style );

Now we'll create a set of buttons and link them up to their actions when the click event is triggered.

my $btnButton1 = Wx::Button->new( $pnlBtns, -1, 'Button 1'); EVT_BUTTON( $pnlBtns, $btnButton1, \&btnButton1Clicked ); my $btnButton2 = Wx::Button->new( $pnlBtns, -1, 'Button 2'); EVT_BUTTON( $pnlBtns, $btnButton2, \&btnButton2Clicked );

With the buttons created, we'll add them to our $btnBox:

$btnBox->Add( $btnButton1, 1, wxALIGN_BOTTOM, 0 ); $btnBox->Add( $btnButton2, 1, wxALIGN_BOTTOM, 0 );

Here we have told the layout manager that we want these buttons to be aligned along the bottom of the panel.

And then we set this button panel to use the sizer $btnBox:

$pnlBtns->SetSizer($btnBox);

With that, lets now set $pnl4's Sizer

$pnl4->SetSizer($pnl4Vbox);

Finally, we need to ->Add() all the panels to the $vbox for this frame:

$vbox->Add( $pnl1, 1, wxEXPAND | wxALL, 3); $vbox->Add( $pnl2, 1, wxEXPAND | wxALL, 3); $vbox->Add( $pnl3, 1, wxEXPAND | wxALL, 3); $vbox->Add( $pnl4, 1, wxEXPAND | wxALL, 3);

In these ->Adds()'s we've used wxEXPAND and wxALL to have the panel expand to fill all space available to it, the '3' in the last parameter is the size in Pixels for the border.

( see http://docs.wxwidgets.org/stable/wx_sizeroverview.html#boxsizerprogramming for more details )

Lastly, we set the Frames Sizer to the $vbox and then return $self:

$self->SetSizer( $vbox ); return $self; }

That's it for the instantiation of this class.

To be complete, the button subs follow:

sub btnButton1Clicked { my( $self, $event ) = @_; print "Button 1\n"; } sub btnButton2Clicked { my( $self, $event ) = @_; print "Button 2\n"; }

That's it.

I don't profess to have used any 'best practice' here, as I'm still learning the ropes with Wx myself.

What I hope to show here is how to use BoxSizer to get a fairly complex layout up and running quickly.

Something I couldn't find myself.

I managed to get a fairly good understanding of things after reading the wxPython Wiki. ( http://wiki.wxpython.org/AnotherTutorial ).

The full code follows:

package BoxSizerExampleFrame; use strict; use warnings; use Wx qw /:everything/; use Wx::Event qw/EVT_BUTTON/; use base 'Wx::Frame'; sub new { my $class = shift; my $self = $class->SUPER::new( undef, -1, 'Jabber Frame', [-1,-1], [600, 400], ); my $vbox = Wx::BoxSizer->new( wxVERTICAL ); my $pnl1 = Wx::Panel->new($self, -1); my $pnl2 = Wx::Panel->new($self, -1); my $pnl3 = Wx::Panel->new($self, -1); my $pnl4 = Wx::Panel->new($self, -1); my $lbl1 = Wx::StaticText->new( $pnl1, # parent -1, # id, "Testing: 1", # label [5,10], # position ); my $lbl2 = Wx::StaticText->new( $pnl2, # parent -1, # id, "Testing: 2", # label [5,10], # position ); my $lbl3 = Wx::StaticText->new( $pnl3, # parent -1, # id, "Testing: 3", # label [5,10], # position ); # now we want to create a vbox for the 4th panel # in this we will put button and other panels my $pnl4Vbox = Wx::BoxSizer->new( wxVERTICAL ); # we'll create a button panel and place the buttons # horizontally my $btnBox = Wx::BoxSizer->new( wxHORIZONTAL ); my $pnlBtns = Wx::Panel->new( $pnl4, #parent -1, # id [-1,-1], # position [-1,-1], # size 0 # border style ); my $pnl4Text = Wx::Panel->new( $pnl4, #parent -1, # id [-1,-1], # position [-1,-1], # size 0, #wxSIMPLE_BORDER # border style ); my $btnButton1 = Wx::Button->new( $pnlBtns, -1, 'Button 1'); EVT_BUTTON( $pnlBtns, $btnButton1, \&btnButton1Clicked ); my $btnButton2 = Wx::Button->new( $pnlBtns, -1, 'Button 2'); EVT_BUTTON( $pnlBtns, $btnButton2, \&btnButton2Clicked ); $btnBox->Add( $btnButton1, 1, wxALIGN_BOTTOM, 0 ); $btnBox->Add( $btnButton2, 1, wxALIGN_BOTTOM, 0 ); $pnlBtns->SetSizer($btnBox); $pnl4Vbox->Add( $pnl4Text, 1, wxEXPAND, 0); $pnl4Vbox->Add( $pnlBtns, # widget 1, # vertically stretchable wxALIGN_BOTTOM | wxALIGN_RIGHT, # alignment 0 # border pixels ); $pnl4->SetSizer($pnl4Vbox); $vbox->Add( $pnl1, 1, wxEXPAND | wxALL, 3); $vbox->Add( $pnl2, 1, wxEXPAND | wxALL, 3); $vbox->Add( $pnl3, 1, wxEXPAND | wxALL, 3); $vbox->Add( $pnl4, 1, wxEXPAND | wxALL, 3); $self->SetSizer( $vbox ); return $self; } sub btnButton1Clicked { my( $self, $event ) = @_; print "Button 1\n"; } sub btnButton2Clicked { my( $self, $event ) = @_; print "Button 2\n"; } 1;

In reply to RFC for Tutorials: Using BoxSizer Layout Manager in wxPerl by waxhead

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others meditating upon the Monastery: (8)
    As of 2014-04-20 16:57 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      April first is:







      Results (485 votes), past polls