Home  Contents

Menus & toolbars

In this part of the Ruby GTK programming tutorial, we will work with menus & toolbars.

A menubar is one of the most common parts of the GUI application. It is a group of commands located in various menus. While in console applications you have to remember all those arcane commands, here we have most of the commands grouped into logical parts. These are accepted standards that further reduce the amount of time spending to learn a new application.

Simple menu

In our first example, we will create a menubar with one file menu. The menu will have only one menu item. By selecting the item the application quits.


#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a simple menu
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

    def initialize
        super
    
        set_title "Simple menu"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 250, 200
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        modify_bg Gtk::STATE_NORMAL, Gdk::Color.new(6400, 6400, 6440)
        
        mb = Gtk::MenuBar.new

        filemenu = Gtk::Menu.new
        filem = Gtk::MenuItem.new "File"
        filem.set_submenu filemenu
       
        exit = Gtk::MenuItem.new "Exit"
        exit.signal_connect "activate" do
            Gtk.main_quit
        end
        
        filemenu.append exit

        mb.append filem

        vbox = Gtk::VBox.new false, 2
        vbox.pack_start mb, false, false, 0

        add vbox
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main

This is a small example with minimal menubar functionality.

 mb = Gtk::MenuBar.new

MenuBar widget is created. This is a container for the menus.

 filemenu = Gtk::Menu.new
 filem = Gtk::MenuItem.new "File"
 filem.set_submenu filemenu

Toplevel MenuItem is created.

 exit = Gtk::MenuItem.new "Exit"
 exit.signal_connect "activate" do
     Gtk.main_quit
 end

 filemenu.append exit

Exit MenuItem is created and appended to the File MenuItem.

 mb.append filem

Toplevel MenuItem is appended to the MenuBar widget.

 vbox = Gtk::VBox.new false, 2
 vbox.pack_start mb, false, false, 0

Unlike in other toolkits, we have to take care of the layout management of the menubar ourselves. We put the menubar into the vertical box.


Simple menu
Figure: Simple menu

Our final example demonstrates how to create a submenu.


#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a submenu
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

    def initialize
        super
    
        set_title "Submenu"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 250, 200
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        modify_bg Gtk::STATE_NORMAL, Gdk::Color.new(6400, 6400, 6440)
        
        mb = Gtk::MenuBar.new

        filemenu = Gtk::Menu.new
        filem = Gtk::MenuItem.new "File"
        filem.set_submenu filemenu

        mb.append filem
        
        imenu = Gtk::Menu.new

        importm = Gtk::MenuItem.new "Import"
        importm.set_submenu imenu

        inews = Gtk::MenuItem.new "Import news feed..."
        ibookmarks = Gtk::MenuItem.new "Import bookmarks..."
        imail = Gtk::MenuItem.new "Import mail..."

        imenu.append inews
        imenu.append ibookmarks
        imenu.append imail

        filemenu.append importm
        
        exit = Gtk::MenuItem.new "Exit"
        exit.signal_connect "activate" do
            Gtk.main_quit
        end
        
        filemenu.append exit

        vbox = Gtk::VBox.new false, 2
        vbox.pack_start mb, false, false, 0

        add vbox
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main

Submenu creation.

 imenu = Gtk::Menu.new

A submenu is a Menu.

 importm = Gtk::MenuItem.new "Import"
 importm.set_submenu imenu

It is a submenu of a menu item, which belogs to toplevel file menu.

 inews = Gtk::MenuItem.new "Import news feed..."
 ibookmarks = Gtk::MenuItem.new "Import bookmarks..."
 imail = Gtk::MenuItem.new "Import mail..."

 imenu.append inews
 imenu.append ibookmarks
 imenu.append imail

Submenu has its own menu items.


Submenu
Figure: Submenu

Image menu

In the next example, we will further explore the menus. We will add images and accelerators to our menu items. Accelerators are keyboard shortcuts for activating a menu item.


#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a menu with
# images, accelerators and a separator
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

    def initialize
        super
    
        set_title "Image menu"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 250, 200
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        modify_bg Gtk::STATE_NORMAL, Gdk::Color.new(6400, 6400, 6440)
        
        mb = Gtk::MenuBar.new

        filemenu = Gtk::Menu.new
        filem = Gtk::MenuItem.new "File"
        filem.set_submenu filemenu
        
        agr = Gtk::AccelGroup.new
        add_accel_group agr

        newi = Gtk::ImageMenuItem.new Gtk::Stock::NEW, agr
        key, mod = Gtk::Accelerator.parse "N"
        newi.add_accelerator("activate", agr, key, 
            mod, Gtk::ACCEL_VISIBLE)
        filemenu.append newi

        openm = Gtk::ImageMenuItem.new Gtk::Stock::OPEN, agr
        key, mod = Gtk::Accelerator.parse "O"
        openm.add_accelerator("activate", agr, key, 
            mod, Gtk::ACCEL_VISIBLE)
        filemenu.append openm

        sep = Gtk::SeparatorMenuItem.new
        filemenu.append sep

        exit = Gtk::ImageMenuItem.new Gtk::Stock::QUIT, agr
        key, mod = Gtk::Accelerator.parse "Q"
        exit.add_accelerator("activate", agr, key, 
            mod, Gtk::ACCEL_VISIBLE)

        exit.signal_connect "activate" do
            Gtk.main_quit
        end
        filemenu.append exit

        mb.append filem

        vbox = Gtk::VBox.new false, 2
        vbox.pack_start mb, false, false, 0

        add vbox
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main

Our example shows a toplevel menu item with three sublevel menu items. Each of the menu items has a image and an accelerator. The accelerator for the quit menu item is active.

 agr = Gtk::AccelGroup.new
 add_accel_group agr

To work with accelerators, we create a global AccelGroup object. It will be used later.

 newi = Gtk::ImageMenuItem.new Gtk::Stock::NEW, agr
 key, mod = Gtk::Accelerator.parse "N"
 newi.add_accelerator("activate", agr, key, 
     mod, Gtk::ACCEL_VISIBLE)
 filemenu.append newi

ImageMenuItem is created. The image comes from the stock of images. We create also a Ctrl+N accelerator.

 sep = Gtk::SeparatorMenuItem.new
 filemenu.append sep

These lines create a separator. It is used to put menu items into logical groups.


Image menu
Figure: Image menu

Menus group commands that we can use in application. Toolbars provide a quick access to the most frequently used commands.

Simple toolbar

Next we create a simple toolbar.


#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a toolbar
# widget
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

    def initialize
        super
    
        set_title "Toolbar"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 250, 200
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        toolbar = Gtk::Toolbar.new
        toolbar.set_toolbar_style Gtk::Toolbar::Style::ICONS

        newtb = Gtk::ToolButton.new Gtk::Stock::NEW
        opentb = Gtk::ToolButton.new Gtk::Stock::OPEN
        savetb = Gtk::ToolButton.new Gtk::Stock::SAVE
        sep = Gtk::SeparatorToolItem.new
        quittb = Gtk::ToolButton.new Gtk::Stock::QUIT

        toolbar.insert 0, newtb
        toolbar.insert 1, opentb
        toolbar.insert 2, savetb
        toolbar.insert 3, sep
        toolbar.insert 4, quittb
        
        quittb.signal_connect "clicked" do
            Gtk.main_quit
        end

        vbox = Gtk::VBox.new false, 2
        vbox.pack_start toolbar, false, false, 0

        add(vbox)
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main

The example shows a toolbar and four tool buttons.

 toolbar = Gtk::Toolbar.new

A Toolbar widget is created.

 toolbar.set_toolbar_style Gtk::Toolbar::Style::ICONS

On toolbar, we show only icons. No text.

 newtb = Gtk::ToolButton.new Gtk::Stock::NEW

A ToolButton with an image from stock is created. The image comes from the built-in stock of images.

 sep = Gtk::SeparatorToolItem.new

This is a separator. It can be used to put toolbar buttons into logical groups.

 toolbar.insert 0, newtb
 toolbar.insert 1, opentb
 ...

Toolbar buttons are inserted into the toolbar widget.


Toolbar
Figure: Toolbar

Undo redo

The following example demonstrates, how we can deactivate toolbar buttons on the toolbar. It is a common practise in GUI programming. For example the save button. If we save all changes of our document to the disk, the save button is deactivated in most text editors. This way the application indicates to the user, that all changes are already saved.


#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows how to 
# activate/deactivate a ToolButton
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

    
    def initialize
        super
    
        set_title "Undo redo"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        @count = 2
        
        init_ui

        set_default_size 250, 200
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        toolbar = Gtk::Toolbar.new
        toolbar.set_toolbar_style Gtk::Toolbar::Style::ICONS

        @undo = Gtk::ToolButton.new Gtk::Stock::UNDO
        @redo = Gtk::ToolButton.new Gtk::Stock::REDO
        sep = Gtk::SeparatorToolItem.new
        quit = Gtk::ToolButton.new Gtk::Stock::QUIT

        toolbar.insert 0, @undo
        toolbar.insert 1, @redo
        toolbar.insert 2, sep
        toolbar.insert 3, quit
        
        @undo.signal_connect "clicked" do
            on_undo
        end
         
        @redo.signal_connect "clicked" do
            on_redo
        end
        
        quit.signal_connect "clicked" do
            Gtk.main_quit
        end

        vbox = Gtk::VBox.new false, 2
        vbox.pack_start toolbar, false, false, 0

        self.add vbox

    end
    
    def on_undo

        @count = @count - 1

        if @count <= 0
            @undo.set_sensitive false
            @redo.set_sensitive true
        end
    end


    def on_redo
        @count = @count + 1

        if @count >= 5
            @redo.set_sensitive false
            @undo.set_sensitive true
        end
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main

Our example creates undo and redo buttons from the GTK stock resources. After several clicks each of the buttons is deactivated. The buttons are grayed out.

 @count = 2

The @count variable decides, which button is activated or deactivated.

 @undo = Gtk::ToolButton.new Gtk::Stock::UNDO
 @redo = Gtk::ToolButton.new Gtk::Stock::REDO

We have two tool buttons. Undo and redo tool buttons. Images come from the stock resources.

 @undo.signal_connect "clicked" do
     on_undo
 end         

Clicking on the undo button, we trigger the on_undo method.

 if @count <= 0
     @undo.set_sensitive false
     @redo.set_sensitive true
 end

To activate or deactivate a widget, we use the set_sensitive method


Undo redo
Figure: Undo redo

In this chapter of the Ruby GTK tutorial, we showed, how to work with menus & toolbars.