In this chapter we will show how to lay out our widgets in windows or dialogs.
When we design the GUI of our application, we decide what widgets we will use and how we will organize those widgets in the application. To organize our widgets, we use specialized non visible widgets called layout containers. In this chapter, we will mention Alignment, Fixed, VBox and Table.
The Fixed container places child widgets at fixed positions and with fixed sizes. This container performs no automatic layout management. In most applications, we don't use this container. There are some specialized areas, where we use it. For example games, specialized applications that work with diagrams, resizable components that can be moved (like a chart in a spreadsheet application), small educational examples.
#!/usr/bin/ruby
# ZetCode Ruby GTK tutorial
#
# In this program, we lay out widgets
# using absolute positioning
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'gtk2'
class RubyApp < Gtk::Window
def initialize
super
set_title "Fixed"
signal_connect "destroy" do
Gtk.main_quit
end
init_ui
set_default_size 300, 280
set_window_position Gtk::Window::POS_CENTER
show_all
end
def init_ui
modify_bg Gtk::STATE_NORMAL, Gdk::Color.new(6400, 6400, 6440)
begin
bardejov = Gdk::Pixbuf.new "bardejov.jpg"
rotunda = Gdk::Pixbuf.new "rotunda.jpg"
mincol = Gdk::Pixbuf.new "mincol.jpg"
rescue IOError => e
puts e
puts "cannot load images"
exit
end
image1 = Gtk::Image.new bardejov
image2 = Gtk::Image.new rotunda
image3 = Gtk::Image.new mincol
fixed = Gtk::Fixed.new
fixed.put image1, 20, 20
fixed.put image2, 40, 160
fixed.put image3, 170, 50
add fixed
end
end
Gtk.init
window = RubyApp.new
Gtk.main
In our example, we show three small images on the window. We explicitely specify the x, y coordinates, where we place these images.
modify_bg Gtk::STATE_NORMAL, Gdk::Color.new(6400, 6400, 6440)
For better visual experience, we change the background color to dark gray.
bardejov = Gdk::Pixbuf.new "bardejov.jpg"
We load the image from the disk to the Pixbuf object.
image1 = Gtk::Image.new bardejov image2 = Gtk::Image.new rotunda image3 = Gtk::Image.new mincol
The Image is a widget, that is used to display images. It takes Pixbuf object in the constructor.
fixed = Gtk::Fixed.new
We create the Fixed container.
fixed.put image1, 20, 20
We place the first image at x=20, y=20 coordinates.
add fixed
Finally, we add the Fixed container to the Window.
The Alignment container controls the alignment and the size of its child widget.
#!/usr/bin/ruby
# ZetCode Ruby GTK tutorial
#
# In this program, we position two buttons
# in the bottom right corner of the window.
# We use horizontal and vertical boxes.
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'gtk2'
class RubyApp < Gtk::Window
def initialize
super
set_title "Buttons"
signal_connect "destroy" do
Gtk.main_quit
end
init_ui
set_default_size 260, 150
set_window_position Gtk::Window::POS_CENTER
show_all
end
def init_ui
vbox = Gtk::VBox.new false, 5
hbox = Gtk::HBox.new true, 3
valign = Gtk::Alignment.new 0, 1, 0, 0
vbox.pack_start valign
ok = Gtk::Button.new "OK"
ok.set_size_request 70, 30
close = Gtk::Button.new "Close"
hbox.add ok
hbox.add close
halign = Gtk::Alignment.new 1, 0, 0, 0
halign.add hbox
vbox.pack_start halign, false, false, 3
add vbox
end
end
Gtk.init
window = RubyApp.new
Gtk.main
In the code example, we place two buttons into the right bottom corner of the window. To accomplish this, we use one horizontal box and one vertical box and two alignment containers.
valign = Gtk::Alignment.new 0, 1, 0, 0
This will put the child widget to the bottom.
vbox.pack_start valign
Here we place the Alignment widget into the vertical box.
hbox = Gtk::HBox.new true, 3 ... ok = Gtk::Button.new "OK" ok.set_size_request 70, 30 close = Gtk::Button.new "Close" hbox.add ok hbox.add close
We create a horizontal box and put two buttons inside it.
halign = Gtk::Alignment.new 1, 0, 0, 0 halign.add hbox vbox.pack_start halign, false, false, 3
This will create an alignment container that will place its child widget to the right. We add the horizontal box into the alignment container and pack the alignment container into the vertical box. We must keep in mind that the alignment container takes only one child widget. That's why we must use boxes.
The Table widget arranges widgets in rows and columns.
#!/usr/bin/ruby
# ZetCode Ruby GTK tutorial
#
# In this program we create a skeleton of
# a calculator. We use the Table widget.
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'gtk2'
class RubyApp < Gtk::Window
def initialize
super
set_title "Calculator"
signal_connect "destroy" do
Gtk.main_quit
end
init_ui
set_default_size 300, 250
set_window_position Gtk::Window::POS_CENTER
show_all
end
def init_ui
vbox = Gtk::VBox.new false, 2
mb = Gtk::MenuBar.new
filemenu = Gtk::Menu.new
file = Gtk::MenuItem.new "File"
file.set_submenu filemenu
mb.append file
vbox.pack_start mb, false, false, 0
table = Gtk::Table.new 5, 4, true
table.attach Gtk::Button.new("Cls"), 0, 1, 0, 1
table.attach Gtk::Button.new("Bck"), 1, 2, 0, 1
table.attach Gtk::Label.new, 2, 3, 0, 1
table.attach Gtk::Button.new("Close"), 3, 4, 0, 1
table.attach Gtk::Button.new("7"), 0, 1, 1, 2
table.attach Gtk::Button.new("8"), 1, 2, 1, 2
table.attach Gtk::Button.new("9"), 2, 3, 1, 2
table.attach Gtk::Button.new("/"), 3, 4, 1, 2
table.attach Gtk::Button.new("4"), 0, 1, 2, 3
table.attach Gtk::Button.new("5"), 1, 2, 2, 3
table.attach Gtk::Button.new("6"), 2, 3, 2, 3
table.attach Gtk::Button.new("*"), 3, 4, 2, 3
table.attach Gtk::Button.new("1"), 0, 1, 3, 4
table.attach Gtk::Button.new("2"), 1, 2, 3, 4
table.attach Gtk::Button.new("3"), 2, 3, 3, 4
table.attach Gtk::Button.new("-"), 3, 4, 3, 4
table.attach Gtk::Button.new("0"), 0, 1, 4, 5
table.attach Gtk::Button.new("."), 1, 2, 4, 5
table.attach Gtk::Button.new("="), 2, 3, 4, 5
table.attach Gtk::Button.new("+"), 3, 4, 4, 5
vbox.pack_start Gtk::Entry.new, false, false, 0
vbox.pack_end table, true, true, 0
add vbox
end
end
Gtk.init
window = RubyApp.new
Gtk.main
We use the Table widget to create a calculator skeleton.
table = Gtk::Table.new 5, 4, true
We create a table widget with 5 rows and 4 columns. The third parameter is the homogenous parameter. If set to true, all the widgets in the table are of same size. The size of all widgets is equal to the largest widget in the table container.
table.attach Gtk::Button.new("Cls"), 0, 1, 0, 1
We attach a button to the table container. To the top-left cell of the table. The first two parameters are the left and right sides of the cell, the last two parameters are the top and left sides of the cell.
vbox.pack_end table, true, true, 0
We pack the table widget into the vertical box.
Next we will create a more advanced example. We show a window, that can be found in the JDeveloper IDE.
#!/usr/bin/ruby
# ZetCode Ruby GTK tutorial
#
# This is a more complicated layout example.
# We use Alignment and Table widgets.
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009
require 'gtk2'
class RubyApp < Gtk::Window
def initialize
super
set_title "Windows"
signal_connect "destroy" do
Gtk.main_quit
end
init_ui
set_default_size 300, 250
set_window_position Gtk::Window::POS_CENTER
show_all
end
def init_ui
set_border_width 15
table = Gtk::Table.new 8, 4, false
table.set_column_spacings 3
title = Gtk::Label.new "Windows"
halign = Gtk::Alignment.new 0, 0, 0, 0
halign.add title
table.attach(halign, 0, 1, 0, 1, Gtk::FILL,
Gtk::FILL, 0, 0)
frame = Gtk::Frame.new
table.attach(frame, 0, 2, 1, 3, Gtk::FILL | Gtk::EXPAND,
Gtk::FILL | Gtk::EXPAND, 1, 1)
activate = Gtk::Button.new "Activate"
activate.set_size_request 50, 30
table.attach(activate, 3, 4, 1, 2, Gtk::FILL,
Gtk::SHRINK, 1, 1)
valign = Gtk::Alignment.new 0, 0, 0, 0
close = Gtk::Button.new "Close"
close.set_size_request 70, 30
valign.add close
table.set_row_spacing 1, 3
table.attach(valign, 3, 4, 2, 3, Gtk::FILL,
Gtk::FILL | Gtk::EXPAND, 1, 1)
halign2 = Gtk::Alignment.new 0, 1, 0, 0
help = Gtk::Button.new "Help"
help.set_size_request 70, 30
halign2.add help
table.set_row_spacing 3, 6
table.attach(halign2, 0, 1, 4, 5, Gtk::FILL,
Gtk::FILL, 0, 0)
ok = Gtk::Button.new "OK"
ok.set_size_request 70, 30
table.attach(ok, 3, 4, 4, 5, Gtk::FILL,
Gtk::FILL, 0, 0)
add table
end
end
Gtk.init
window = RubyApp.new
Gtk.main
The code example shows, how we can create a similar window in Ruby GTK.
table = Gtk::Table.new 8, 4, false table.set_column_spacings 3
The example is based on the Table container. There will be 3px space between columns.
title = Gtk::Label.new "Windows"
halign = Gtk::Alignment.new 0, 0, 0, 0
halign.add title
table.attach(halign, 0, 1, 0, 1, Gtk::FILL,
Gtk::FILL, 0, 0)
This code creates a label, that is aligned to the left. The label is placed in the first row of the Table container.
frame = Gtk::Frame.new
table.attach(frame, 0, 2, 1, 3, Gtk::FILL | Gtk::EXPAND,
Gtk::FILL | Gtk::EXPAND, 1, 1)
The frame view widget spans two rows and two columns. We make the widget non editable and hide the cursor.
valign = Gtk::Alignment.new 0, 0, 0, 0
close = Gtk::Button.new "Close"
close.set_size_request 70, 30
valign.add close
table.set_row_spacing 1, 3
table.attach(valign, 3, 4, 2, 3, Gtk::FILL,
Gtk::FILL | Gtk::EXPAND, 1, 1)
We put the close button next to the frame widget into the fourth column. (we count from zero) We add the button into the alignment widget, so that we can align it to the top.
In this part of the Ruby GTK tutorial, we mentioned layout management of widgets.