Hello World in Ruby/GTK


First Script

As is usual with tutorials like this, our first script is one which displays "Hello World". Running following script will show a button like the result below.

Program hello.rb:

require 'gtk'

window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL)
button = Gtk::Button.new('Hello World')
window.add button
button.show
window.show
Gtk.main

Result:

The title bar and bottom bar (resize bar) are added by WindowMaker, the window manager the author use.

This simple code is enough to create a button on the screen, and the button responds to a mouse click by changing its appearance as pushed down. But it's no more than a change on the surface and there is no way of exiting except to kill by using the shell.

Description of the script:


How to make a button to perform callbacks.

In the previous example, the button can be pushed down but this brings no reaction. In next example, pushing down the button will prints "Hello World" to the standard output.

Program hello2.rb:

require 'gtk'

window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL)
button = Gtk::Button.new("Hello World")

button.signal_connect('clicked') {
  print "Hello World\n"
}

window.add button
button.show
window.show
Gtk.main

Following portion of above code is different from previous example.

button.signal_connect('clicked') {
  print "Hello World\n"
}
Gtk adopts signals and callbacks mechanism. For example, when a button is clicked with the pointer, `clicked' signal is emitted. When a signal is emitted, callbacks (a.k.a. signal handlers) associated with the signal are called. Some signals are peculiar to specific widgets as `clicked' to buttons, and others are common among all kinds of widgets as `destroy' is.

With ruby/gtk, signal handler is defined as a block given to signal_connect. In above example, the block contents is executed when a 'clicked' signal is emitted by the button widget.


Add Callback to 'delete_event'

In gtk, events of X Window System are also integrated into signal mechanism and dealt with signal_connect. For example, when the button on the right end of the window titlebar which WindowMaker attached is clicked, a delete event will be issued. In order to make our window to respond to the delete event and exit the program, add signal handler as follows:

Program hello3.rb:

require 'gtk'

window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL)
button = Gtk::Button.new('Hello World')

window.signal_connect('delete_event') {
  print "delete event occurred\n"
  false
}

button.signal_connect('destroy') {
  print "destroy\n"
  exit
}

button.signal_connect('clicked') {
  print "Hello World\n"
}

window.add button
button.show
window.show
Gtk.main

The delete event from window manager is delivered to the toplevel window. So the event handler should be defined as follows:

window.signal_connect('delete_event') {
  print "delete event occurred\n"
  false
}
Event handlers for 'delete_event' must return true or false depending on the result of event handling, e.g. request the user to confirm. In above example, 'destroy' signal handler is defined as follows:
window.signal_connect('destroy') {
  print "destroy\n"
  exit
}
This handler will simply print "destroy" and exits the program. If exit is not called, the window will disappear and the program will not terminate.
Window Title

Toplevel windows have its own title. The title of the window is displayed on the titlebar which window manager attaches. The title is set by set_title.

window.set_title 'Hello'

Result:

Compare the results of this and the first example.


Common Procedure of Widget Creation

Common procedure for creating widgets under ruby/gtk is summarized as follows:

  1. Create widget by calling class method new of the widget class.
    (e.g. button = Gtk::Button.new)
  2. Connect appropriate handlers to signals and events if necessary.
  3. Configure widget's attributes if necessary.
  4. Pack the widget into a container widget.
    (e.g. window.add button)
  5. Show the widget.
    (e.g. button.show)
Although there is no `right' moment to invoke widget's show method, at least the toplevel window should be shown after all other widgets on the window. Because doing so prevents the user from seeing the widgets in the middle of their creation.
Coding Style

Ruby code in this tutorial follows coding style described below. The basics of the style is to save the amount of typing.