wxRuby recently made it to version 2.0, and has become a robust platform for developing software with a graphical user interface, or GUI. Let us get started with wxRuby, and create a simple program.
Installation
Installation is covered in http://wxruby.rubyforge.org/wiki/wiki.pl?Installation. You will need wxWidgets installed on your Linux platform: get it from your repository. On Ubuntu, I used synaptic to search for wxWidgets, and installed libwxgtk2.8-0, which also pulled in libwxbase2.8-0. Once you have these, rubygems does the rest: sudo gem install wxruby.
Simplest Example
The simplest example just creates a basic frame. The code is in three pieces. The first piece is the loader, which tries to install wxruby; if rubygems is not installed by default (should not happen in newer Ruby distributions) then it will require rubygems before trying to find wxruby. The second piece defines the SimpleFrame class. This class is a subclass of the wxWidgets class Frame. The namespace for all the wxruby material is 'Wx'. (I like to keep namespaces within my code, but some like to 'include wx' at the start, and then the 'Wx::' parts are optional.)
The SimpleFrame class has an initialize method which calls its parent class. The nil tells the parent there is no parent frame for the SimpleFrame to relate to. The second argument uses a keyword-style format to set the title of the frame.
The third part of the code starts the wx application, and, within the block, creates and shows a SimpleFrame.
# This block ensures that rubygems is present before requiring wx.
begin
require 'wx'
rescue LoadError => no_wx_err
begin
require 'rubygems'
require 'wx'
rescue LoadError
raise no_wx_err
end
end
class SimpleFrame < Wx::Frame
def initialize
super(nil, :title => "Simple Frame Title")
end
end
Wx::App.run do
SimpleFrame.new.show
end
Adding a Menu and Status Bar
The hardest part in learning about any GUI library is to figure out how the different elements can be placed onto the screen. Two basic elements are the menu and status bar. The menu places the commands for your application in an easy to access place, and the status bar provides a method to feed information back to the user.
Adding a menu bar is a three step process. First, a set of menus must be created, containing any submenus or menuitems. Second, these menus must be added to a menubar. And third, the menubar must be added to the frame.
Step 1: creating the menus.
A menu is an instance of Wx::Menu. Before creating a menu, we must create an instance of Wx::Menu and name it. Next, we must add the items we want to display to the menu. Here we meet a useful feature of wxWidgets, which is the standard identifier. Every widget (instance of a wx class) within wxWidgets has a unique ID number. This ID number can be assigned by a user, but there are also several standard ones provided in the library. Useful ones include: ID_ABOUT, ID_EXIT, ID_OPEN, ID_SAVE. If you use a standard identifier for a menu item or button, wxWidgets will automatically give it a name, icon and appearance standard for the platform you are using.
To create a program menu with an About and Quit button, we use:
program_menu = Wx::Menu.new
program_menu.append(Wx::ID_ABOUT)
program_menu.append(Wx::ID_EXIT)
How do we make the menu item do something when you click on it? We associate the menu item widget with a ruby method, so that the method is called every time the menu item is clicked. When we know the ID number of the widget, we can use that to make the association. The evt_menu method in the construction of the menu associates the block with the given ID number. The complete listing below provides some examples of things to do to suit the menu items.
evt_menu(Wx::ID_ABOUT) {about_program}
Step 2: Add the menus to a menubar
The menubar is an instance of Wx::MenuBar. You add menus to the menubar using the append method of menubar. The append method takes the menu itself and the title of the menu. Use an ampersand, &, in the title of the menu to provide the little line for a keyboard shortcut to that menu.
Step 3: Add the menubar to the frame
The easiest step of the three: just tell the frame to set_menu_bar to your menubar instance. Below is the full code to initialise the frame with the menubar:
def initialize
super(nil, :title => "Simple Frame with Menus")
set_menu_bar make_menu_bar
end
def make_menu_bar
# construct menu
menu_bar = Wx::MenuBar.new
# -- menu 1
program_menu = Wx::Menu.new
program_menu.append(Wx::ID_ABOUT)
program_menu.append(Wx::ID_EXIT)
evt_menu(Wx::ID_ABOUT) {about_program}
evt_menu(Wx::ID_EXIT) {exit_program}
menu_bar.append(program_menu, "&Program")
menu_bar
end
Adding a status bar
The status bar is the little strip along the bottom of the screen which contains instructions or information for the user. The bar can be divided into a number of pieces, so different information can be displayed. It is very simple to create a status bar: call the create_status_bar method on the frame, provide it with the number of pieces (fields) you want, and it will be set. Putting text into a field of the status bar is equally easy: call the set_status_text method on the frame, providing it with the string to display and the index (from 0) of the field to display in.
Getting free help
Something I find very useful about status bars and wxWidgets is that each menu item is given a help string. This help string gets displayed in field 0 of the status bar, if you have one! So, include a status bar, and you get free help for your users.
Non-standard menu items
You may want to create your own menu item, not one of the standard ones. To do this, you need to create an instance of MenuItem yourself. This needs at least three items. The first is the Menu in which the item will sit. The second is an ID number - you can write Wx::ID_ANY if you don't care what it is. The third item is the name of the menu. The fourth is an optional help string, which will display in any status bar. The method append_item attaches the item to a menu. evt_menu is again used to associate a block with the menu, and wxRuby is smart enough to recognise an instance of a menu item as well as a widget ID as its parameter.
new_item = Wx::MenuItem.new(program_menu, Wx::ID_ANY, "Special", "Special menu")
program_menu.append_item(new_item)
evt_menu(new_item) {puts "Special clicked"}
Put it all together, and you should get something like the following screen shot:
Below is the complete program:# This block ensures that rubygems is present before requiring wx.
begin
require 'wx'
rescue LoadError => no_wx_err
begin
require 'rubygems'
require 'wx'
rescue LoadError
raise no_wx_err
end
end
class SimpleFrame < Wx::Frame
def initialize
super(nil, :title => "Simple Frame with Menus")
set_menu_bar make_menu_bar
create_status_bar 2
set_status_text("Hello", 1)
end
def make_menu_bar
# construct menu
menu_bar = Wx::MenuBar.new
# -- menu 1
program_menu = Wx::Menu.new
program_menu.append(Wx::ID_ABOUT)
program_menu.append(Wx::ID_EXIT)
evt_menu(Wx::ID_ABOUT) {about_program}
evt_menu(Wx::ID_EXIT) {exit_program}
new_item = Wx::MenuItem.new(program_menu,
Wx::ID_ANY, "Special", "Special menu")
program_menu.append_item(new_item)
evt_menu(new_item) {puts "Special clicked"}
menu_bar.append(program_menu, "&Planet")
menu_bar
end
def about_program
Wx::MessageDialog.new(self,
"Our first wxRuby program",
"About Program",
Wx::ICON_INFORMATION | Wx::OK).show_modal
end
def exit_program
close
end
end
Wx::App.run do
SimpleFrame.new.show
end
Tip: In Ubuntu, associate ruby with your .rb files, and you can run your wxRuby applications by double clicking on the icon!

