- Notifications
You must be signed in to change notification settings - Fork 8
HowTo : Layout widgets with Sizers
About FAQ User Guide Reference documentation In this HowTo we will take a look at Layout Management in wxRuby, and explain how we can use advanced features and sizers to correctly position widgets inside a wxRuby window.
Instead of "Absolute Positioning", we will use wxRuby’s Sizers, which were designed to help place widgets in a specific manner/layout. There are various sizer classes in wxRuby, each discussed briefly here with an example.
Absolute positioning, also known as fixed positioning, uses explicit coordinates when placing widgets. This results in a “fixed position” of the widget, which will not adapt to any changes in the screen size.
Furthermore, making changes to the layout with absolute positioning is trickier once you have a lot of widgets in your window. On the other hand, with Sizers you can change the Sizer’s settings, and all the widgets in it will be effected as well.
Another major advantage of Sizers, is that you can place a Sizer within another, allowing for complex layout patterns.
A small example using absolute positioning.
require 'wx' class MyWindow < Wx::Frame def initialize(title) super(nil, title: title) @panel = Wx::Panel.new(self) text = Wx::StaticText.new(@panel, label: 'Hello World', pos: [50, 50]) button = Wx::Button.new(@panel, label: 'Press Me', pos: [200, 50]) rb = Wx::RadioButton.new(@panel, label: 'Pizza', pos: [50, 120]) cb = Wx::ComboBox.new(@panel, value: 'Kittens', pos: [200, 120]) centre end end Wx::App.run do window = MyWindow.new("wxRuby Sizer Guide") window.show endOutput of the above code:

The steps for creating a basic Sizer are fairly simple.
- First, create the Sizer you want.
- Create a few widgets.
- Insert them into the Sizer using the #add method.
Remember, you can create "nested sizers" by simply creating (a) sizer(s) and inserting into another sizer. This allows for greater flexibility and customizability in widget layouts. The below example will demonstrate this.
Furthermore, the #add method has three common arguments which you’ll find on almost all Sizers.
The first is proportion, which controls how much the widgets grows if the window is re-sized. If the proportion is zero, then it won’t change. If it’s 1 or above, it will. Values above 1 are used to decide the ratio with which the widget will grow, relative to the others.
The flag parameter is used to enable certain options, whereas the border parameter is used to define the padding between widgets/rows/columns in the sizers. The border requires the flag parameter to have certain flags enabled to actually work (such as Wx::Direction::ALL, Wx::Dirtection::BOTTOM etc).
An example on how to use the wxRuby BoxSizer (follow the link for full tutorial and explanation).
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 endOutput of the above code:

An example on how to use the wxRuby StaticBoxSizer (follow the link for full tutorial).
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 sbsizer = Wx::StaticBoxSizer.new(Wx::StaticBox.new(@panel, label: 'Box'), Wx::VERTICAL) button1 = Wx::Button.new(@panel, label: 'Button 1') sbsizer.add(button1, Wx::SizerFlags.new.border(Wx::LEFT|Wx::RIGHT|Wx::TOP, 5)) button2 = Wx::Button.new(@panel, label: 'Button 2') sbsizer.add(button2, Wx::SizerFlags.new.border(Wx::LEFT|Wx::RIGHT|Wx::BOTTOM, 5)) sizer.add(sbsizer, Wx::SizerFlags.new.border(Wx::ALL, 10)) @panel.sizer = sizer centre end end Wx::App.run do window = MyWindow.new("wxRuby Sizer Guide") window.show endOutput of the above code:

An example on how to use the wxRuby GridSizer (Follow link for full tutorial).
require 'wx' class MyWindow < Wx::Frame def initialize(title) super(nil, title: title) @panel = Wx::Panel.new(self) grid = Wx::GridSizer.new(3, 3, 5, 5) [ [Wx::Button.new(@panel, label: "1"), 0, Wx::EXPAND], [Wx::Button.new(@panel, label: "2"), 0, Wx::EXPAND], [Wx::Button.new(@panel, label: "3"), 0, Wx::EXPAND], [Wx::Button.new(@panel, label: "4"), 0, Wx::EXPAND], [Wx::Button.new(@panel, label: "5"), 0, Wx::EXPAND], [Wx::Button.new(@panel, label: "6"), 0, Wx::EXPAND], [Wx::Button.new(@panel, label: "7"), 0, Wx::EXPAND], [Wx::Button.new(@panel, label: "8"), 0, Wx::EXPAND], [Wx::Button.new(@panel, label: "9"), 0, Wx::EXPAND] ].each { |btn, prop, f| grid.add(btn, prop, f) } @panel.sizer = grid centre end end Wx::App.run do window = MyWindow.new("wxRuby Sizer Guide") window.show endOutput of the above code:

An example on how to use the wxRuby FlexGridSizer (Follow link for full tutorial).
require 'wx' class MyWindow < Wx::Frame def initialize(title) super(nil, title: title) @panel = Wx::Panel.new(self) wrapper = Wx::HBoxSizer.new sizer = Wx::FlexGridSizer.new(3, 2, 5, 5) [[Wx::StaticText.new(@panel, label: 'Username')], [Wx::TextCtrl.new(@panel), 0, Wx::EXPAND], [Wx::StaticText.new(@panel, label: 'Password')], [Wx::TextCtrl.new(@panel), 0, Wx::EXPAND], [Wx::StaticText.new(@panel, label: 'Address')], [Wx::TextCtrl.new(@panel, style: Wx::TE_MULTILINE|Wx::TE_NO_VSCROLL), 0, Wx::EXPAND] ].each { |args| sizer.add(*args) } sizer.add_growable_row(2, 1) sizer.add_growable_col(1, 1) wrapper.add(sizer, Wx::SizerFlags.new(1).expand.border(Wx::ALL, 15)) @panel.sizer = wrapper centre end end Wx::App.run do window = MyWindow.new("wxRuby Sizer Guide") window.show endOutput of the above code:

An example on how to use the wxRuby GridBagSizer (Follow link for full tutorial).
require 'wx' class MyWindow < Wx::Frame def initialize(title) super(nil, title: title) @panel = Wx::Panel.new(self) wrapper = Wx::HBoxSizer.new sizer = Wx::GridBagSizer.new(5, 5) sizer.add(Wx::StaticText.new(@panel, label: 'A Keypad'), [0,1], flag: Wx::ALIGN_CENTRE) sizer.add(Wx::Button.new(@panel, label: "1"), [1, 0], flag: Wx::EXPAND) sizer.add(Wx::Button.new(@panel, label: "2"), [1, 1], flag: Wx::EXPAND) sizer.add(Wx::Button.new(@panel, label: "3"), [1, 2], flag: Wx::EXPAND) sizer.add(Wx::Button.new(@panel, label: "4"), [2, 0], flag: Wx::EXPAND) sizer.add(Wx::Button.new(@panel, label: "5"), [2, 1], flag: Wx::EXPAND) sizer.add(Wx::Button.new(@panel, label: "6"), [2, 2], flag: Wx::EXPAND) sizer.add(Wx::Button.new(@panel, label: "7"), [3, 0], flag: Wx::EXPAND) sizer.add(Wx::Button.new(@panel, label: "8"), [3, 1], flag: Wx::EXPAND) sizer.add(Wx::Button.new(@panel, label: "9"), [3, 2], flag: Wx::EXPAND) sizer.add_growable_row(1) sizer.add_growable_row(2) sizer.add_growable_row(3) sizer.add_growable_col(0) sizer.add_growable_col(1) sizer.add_growable_col(2) wrapper.add(sizer, proportion: 1, flag: Wx::EXPAND | Wx::ALL, border: 10) @panel.sizer = wrapper centre end end Wx::App.run do window = MyWindow.new("wxRuby Sizer Guide") window.show endOutput of the above code:

An example on how to use the wxRuby WrapSizer (Follow link for full tutorial).
require 'wx' class MyWindow < Wx::Frame def initialize(title) super(nil, title: title) @panel = Wx::Panel.new(self) sizer = Wx::WrapSizer.new(Wx::HORIZONTAL, 0) # or Wx::HWrapSizer.new(0) 15.times do |i| sizer.add(Wx::CheckBox.new(@panel, label: "Option #{'%.2i' % (i+1)}"), 0, Wx::ALL, 12) end @panel.sizer = sizer centre end end Wx::App.run do window = MyWindow.new("wxRuby Sizer Guide") window.show endOutput of the above code:

-
-
Basic Guides
-
Widget Guides
- Frame with panel
- Widgets
- Button widget
- StaticText widget
- TextCtrl widget
- RadioButton widget
- RadioBox widget
- CheckBox widget
- ComboBox widget
- ToggleButton widget
- StaticLine widget
- StaticBox widget
- BitmapButton widget
- StatusBar widget
- MenuBar widget and menus
- ToolBar widget
- Layout widgets with Sizers
- Scrolling
-
Drawing Guides
-
Event Guides
-