HowTo : BoxSizer - mcorino/wxRuby3 GitHub Wiki

     About      FAQ      User Guide      Reference documentation

wxRuby BoxSizer Tutorial

In this tutorial we will discuss the wxRuby BoxSizer Layout Sizer.

The BoxSizer is one of the sizers in wxRuby designed to help with the layout management of widgets in the window. The BoxSizer is the most basic and commonly used Sizer in wxRuby. Every GUI library has a Layout manager like the BoxSizer.

It’s a fairly simple Sizer that simply stacks widgets vertically or horizontally depending on the orientation setting specified at creation. It doesn’t have a lot of utility alone, but when using several BoxSizers nested within each other, complex GUI layouts can be created easily.

wxRuby BoxSizer Example 1

In this example we will create a simple BoxSizer with two widgets placed inside it.

First we create the BoxSizer, passing in either Wx::VERTICAL or Wx::HORIZONTAL to set the orientation of how widgets will be placed.

sizer = Wx::BoxSizer.new(wx.VERTICAL)

Note: wxRuby provides two simple but useful shortcut derivatives that will make code easier to write and read: Wx::HBoxSizer and Wx::VBoxSizer

Next we add individual widgets in this manner.

button1 = Wx::Button.new(@panel, label: 'Button 1')
sizer.add(button1)

Alternatively, we could add them directly like this.

sizer.add(Wx::Button.new(@panel, label: 'Button 1'))

After adding all the widgets we want to, we simply call the #set_sizer method on the panel in which we are creating all these widgets.

@panel.set_sizer(sizer)

The complete code and output is as follows.

require 'wx'

class MyWindow < Wx::Frame
  def initialize(title)
    super(nil, title: title)
    @panel = Wx::Panel.new(self)

    sizer = Wx::BoxSizer.new(Wx::VERTICAL) # or Wx::VBoxSizer.new

    button1 = Wx::Button.new(@panel, label: 'Button 1')
    sizer.add(button1)

    button2 = Wx::Button.new(@panel, label: 'Button 2')
    sizer.add(button2)

    @panel.sizer = sizer

    centre
  end
end

Wx::App.run do
  window = MyWindow.new("wxRuby BoxSizer Guide")
  window.show
end

The output:

screenshot1

wxRuby BoxSizer Example 2

In this example we’ll begin using some of the additional options and parameters to add more functionality to our widgets in the BoxSizer.

The #add method has three additional, optional arguments.

proportion : This argument is 0 by default which means that the size of the widget is unchangeable. Any value above 0 will change the size of the widgets relative to value in the other widgets (for example a widget with proportion 2 will grow twice as much as a widget with proportion 1) as the sizer changes size.

flag : A combination of flags which are used to change certain things about the sizer (no flags are set by default).

border : The amount of padding to be used between widgets (0 by default). Needs to be used together with the appropriate flag (for example, using Wx::ALL will apply padding on all sides).

Below is a simple example using the BoxSizer with a bunch of additional arguments and options enabled.

require 'wx'

class MyWindow < Wx::Frame
  def initialize(title)
    super(nil, title: title)
    @panel = Wx::Panel.new(self)

    sizer = Wx::BoxSizer.new(Wx::VERTICAL) # or Wx::VBoxSizer.new

    button1 = Wx::Button.new(@panel, label: 'Button 1')
    sizer.add(button1, 1, Wx::ALL | Wx::EXPAND, 5)

    button2 = Wx::Button.new(@panel, label: 'Button 2')
    sizer.add(button2, flag: Wx::ALL, border: 5)

    @panel.sizer = sizer

    centre
  end
end

Wx::App.run do
  window = MyWindow.new("wxRuby BoxSizer Guide")
  window.show
end

The first button has the proportion set to 1, so it expands unlike button 2. There is also some extra padding between the two buttons. The output:

screenshot2

Note: As can be seen in the example wxRuby supports either passing the (full set of) optional arguments in positional order or passing them as keyword arguments (all or some, in any order ).

wxRuby BoxSizer Example 3

Now let’s try to make something more practical. For this, we’ll use the rather interesting concept of nested sizers. You can add a Sizer into another Sizer the same way you add widgets, using the #add method.

require 'wx'

class MyWindow < Wx::Frame
  def initialize(title)
    super(nil, title: title)
    @panel = Wx::Panel.new(self)

    sizer = Wx::BoxSizer.new(Wx::VERTICAL) # or Wx::VBoxSizer.new

    #-----------------------
    sub_sizer1 = Wx::BoxSizer.new(Wx::HORIZONTAL) # or Wx::HBoxSizer.new

    text1 = Wx::StaticText.new(@panel, label: 'Username: ')
    sub_sizer1.add(text1, Wx::SizerFlags.new.border(Wx::ALL, 5))
     
    text2 = Wx::TextCtrl.new(@panel)
    sub_sizer1.add(text2, Wx::SizerFlags.new(1).border(Wx::ALL, 5))
    #-----------------------

    #-----------------------
    sub_sizer2 = Wx::HBoxSizer.new

    text3 = Wx::StaticText.new(@panel, label: 'Password: ')
    sub_sizer2.add(text3, Wx::SizerFlags.new.border(Wx::ALL, 5))
     
    text4 = Wx::TextCtrl.new(@panel)
    sub_sizer2.add(text4, Wx::SizerFlags.new(1).border(Wx::ALL, 5))
    #-----------------------

    sizer.add(sub_sizer1, Wx::SizerFlags.new.expand.border(Wx::TOP|Wx::LEFT, 10))
    sizer.add(sub_sizer2, Wx::SizerFlags.new.expand.border(Wx::TOP|Wx::LEFT, 10))

    @panel.sizer = sizer

    centre
  end
end

Wx::App.run do
  window = MyWindow.new("wxRuby Sizer Guide")
  window.show
end

The layout below, despite being fairly simple, would not be possible with just a single Sizer. For such things, we require multiple sizers. Output of the above code:

screenshot3

Other Sizers in wxRuby

There are many other Sizers in wxRuby that you can use instead of BoxSizer. In fact, the best layouts are often the result of combining several different types of Sizers. This can be done by simply nesting them into each other. There is no limitation to this ability.

You can learn more about these sizers by reading the guide on layout managers in wxRuby.

⚠️ **GitHub.com Fallback** ⚠️