Forum: wxRuby multiple forms or panels

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Jason L. (Guest)
on 2009-06-01 20:09
How do I organize widgets in a form when I need them placed in more than
a single column or row?  I leaned how to use BoxSizer and successfully
displayed my widgets in a single column but can't get the next column.

Here is my code, which puts a text, radio, button all in one column, but
what if I wanted my radios over to the right?:

require "rubygems"
require "wx"
include Wx

class MyFrame < Frame
  def initialize
    super(nil, :title => "My Test Frame")

    @panel = Panel.new(self)
    @result = StaticText.new(@panel, :label=>'Result')
    @y = TextCtrl.new(@panel, -1, '10')
    shape_choice = %w(Circular Rectangular Trapezoidal )

    submit_button = Button.new(@panel, :label => 'Calculate')
    my_radio = RadioBox.new(
      @panel,
      :label => "Select Conduit Shape",
      :choices => shape_choice,
      :major_dimension => 1
    )
    @panel_sizer = BoxSizer.new(VERTICAL)
    @panel.set_sizer(@panel_sizer)

    @panel_sizer.add(@y, 0, GROW|ALL, 2)
    @panel_sizer.add(my_radio, 0, GROW|ALL, 2)
    @panel_sizer.add(submit_button, 0, GROW|ALL, 2)
    @panel_sizer.add(@result, 0, GROW|ALL, 2)

    evt_button(submit_button.get_id()) {|cmd_event|
on_submit(cmd_event)}
    evt_radiobox(my_radio.get_id()) {|cmd_event|
on_change_radio(cmd_event)}

    show()
  end

  def on_change_radio(cmd_event)
    @selected_shape = cmd_event.string
  end

  def on_submit(cmd_event)
    y = @y.get_value().to_f
    area = case
      when @selected_shape == 'Circular' then Math::PI * y**2 / 4.0
      when @selected_shape == 'Rectangular' then y * 5.0
      else (5.0 + 2.0 * y) * y
    end

    @result.label = "#{area} square feet"
  end
end

class MinimalApp < App
  def on_init
    MyFrame.new
  end
end

MinimalApp.new.main_loop
Alex F. (Guest)
on 2009-06-01 20:54
(Received via mailing list)
Jason L. wrote:
> How do I organize widgets in a form when I need them placed in more than
> a single column or row?  I leaned how to use BoxSizer and successfully
> displayed my widgets in a single column but can't get the next column.
>

It sounds like you want either Wx::GridSizer or Wx::FlexGridSizer. The
latter allows for variable width columns or rows, so I generally find it
more useful.

There is also Wx::GridBagSizer, which allows cells to span rows or
columns, but I find nesting other simpler sizers easier to use than the
API for it.

alex
Jason L. (Guest)
on 2009-06-01 23:24
Thank you for the pointer. I tried a simple example, doing my best to
read through wxWidgets examples and wxruby docs and - no success. I
created 4 buttons and they all show on top of each other. Can you see
anything I'm doing wrong? Thank you.

I'm doing this:

class MyFrame < Frame
  def initialize
    super(nil)
    panel = Panel.new(self)
    gs = FlexGridSizer.new(2,2,20,20)

    b1 = Button.new(panel, :label=>"one")
    b2 = Button.new(panel, :label=>"two")
    b3 = Button.new(panel, :label=>"three")
    b4 = Button.new(panel, :label=>"four")

    gs.add(b1)
    gs.add(b2)
    gs.add(b3)
    gs.add(b4)

    gs.add_growable_row(1,1)
    gs.add_growable_col(1,1)

    show()
  end
end

class MinimalApp < App
  def on_init
    MyFrame.new
  end
end

MinimalApp.new.main_loop
Peter L. (Guest)
on 2009-06-02 01:07
Jason L. wrote:
> Thank you for the pointer. I tried a simple example, doing my best to
> read through wxWidgets examples and wxruby docs and - no success. I
> created 4 buttons and they all show on top of each other. Can you see
> anything I'm doing wrong? Thank you.
>
> I'm doing this:
>
> class MyFrame < Frame
>   def initialize
>     super(nil)
>     panel = Panel.new(self)
>     gs = FlexGridSizer.new(2,2,20,20)
>
>     b1 = Button.new(panel, :label=>"one")
>     b2 = Button.new(panel, :label=>"two")
>     b3 = Button.new(panel, :label=>"three")
>     b4 = Button.new(panel, :label=>"four")
>
>     gs.add(b1)
>     gs.add(b2)
>     gs.add(b3)
>     gs.add(b4)
>
>     gs.add_growable_row(1,1)
>     gs.add_growable_col(1,1)
>
>     show()
>   end
> end
>
> class MinimalApp < App
>   def on_init
>     MyFrame.new
>   end
> end
>
> MinimalApp.new.main_loop

Two things are not quite right.  First, you don't need the
'add_growable_row' etc as you have declared your grid to be 2x2.  Also,
you have not told the panel about your sizer, so it does not know how to
layout your widgets.  Change the middle part to:

----------------------------------------
    gs.add(b1)
    gs.add(b2)
    gs.add(b3)
    gs.add(b4)

    # gs.add_growable_row(1,1) # delete this
    # gs.add_growable_col(1,1) # delete this
    panel.sizer = gs  # set the sizer

    show()
----------------------------------------

You don't need to create a separate panel to hold your widgets in, and
can instead add the widgets to 'self'.  Personally, I prefer to use
nested combinations of BoxSizers in most cases.  The following example
may be helpful.

----------------------------------------
require 'wx'

class BoxFrame < Wx::Frame
  def initialize
    super(nil, :title => "BoxSizers")

    # create two sub-sizers
    left_sizer = Wx::BoxSizer.new Wx::VERTICAL
    left_sizer.add(Wx::StaticText.new(self, Wx::ID_ANY, "Left side"))
    left_sizer.add(Wx::Button.new(self, Wx::ID_ANY, "Button"))

    right_sizer = Wx::BoxSizer.new Wx::VERTICAL
    right_sizer.add(Wx::StaticText.new(self, Wx::ID_ANY, "Right side"))
    right_sizer.add(Wx::Button.new(self, Wx::ID_ANY, "Button"))

    # add left/right to main sizer with some padding
    main_sizer = Wx::BoxSizer.new Wx::HORIZONTAL
    main_sizer.add(left_sizer, 1, Wx::ALL, 10)
    main_sizer.add(right_sizer, 1, Wx::ALL, 10)

    set_sizer main_sizer
  end
end

class GridFrame < Wx::Frame
  def initialize
    super(nil, :title => "FlexGridSizer")

    main_sizer = Wx::FlexGridSizer.new(2, 2, 10, 20)

    main_sizer.add(Wx::StaticText.new(self, Wx::ID_ANY, "Left side"))
    main_sizer.add(Wx::StaticText.new(self, Wx::ID_ANY, "Right side"))
    main_sizer.add(Wx::Button.new(self, Wx::ID_ANY, "Left Button"))
    main_sizer.add(Wx::Button.new(self, Wx::ID_ANY, "Right Button"))

    set_sizer main_sizer
  end
end

Wx::App.run do
  BoxFrame.new.show
  GridFrame.new.show
end
----------------------------------------

Hope that helps,

    Peter.
Jason L. (Guest)
on 2009-06-02 02:01
ah, I see. Thank you for that clarification. Just what I needed!
This topic is locked and can not be replied to.