Skip to content

HowTo : MenuBar widget and menus

Martin Corino edited this page May 29, 2024 · 2 revisions
     About      FAQ      User Guide      Reference documentation

wxRuby MenuBar Widget and Menus

This wxRuby guide demonstrates how to create a menu using Wx::Menu and Wx::MenuBar widgets, alongside it’s various styles, features and methods. A complete list of options will be included here, alongside several code examples for your convenience.

Creating a simple menu

In this example we’ll create a simple menubar with a File menu.

require 'wx'

class MyWindow < Wx::Frame
  def initialize(title)
    super(nil, title: title)
    @panel = Wx::Panel.new(self)

    #----------------
    menuBar = Wx::MenuBar.new

    fileMenu = Wx::Menu.new
    newFileItem  = fileMenu.append(Wx::ID_NEW,  "&New\tCTRL+N",  'Create New File')
    openFileItem = fileMenu.append(Wx::ID_OPEN, "&Open\tCTRL+O", 'Open File')
    saveFileItem = fileMenu.append(Wx::ID_SAVE, "&Save\tCTRL+S", 'Save File')

    evt_menu(newFileItem, :new_file)
    evt_menu(openFileItem, :open_file)
    evt_menu(saveFileItem, :save_file)

    menuBar.append(fileMenu, 'File')
    #----------------

    self.set_menu_bar(menuBar)
    
    centre
  end
  
  def new_file(_)
    puts 'New File'
  end

  def open_file(_)
    puts 'Open File'
  end

  def save_file(_)
    puts 'Save File'
  end
  
end

Wx::App.run do
  window = MyWindow.new("wxRuby MenuBar Guide")
  window.show
end

Step by step

We start off by creating a Wx::MenuBar called menuBar. Any menus that we create later will be added into this menubar.

    menuBar = Wx::MenuBar.new

Next we create a Wx::Menu called fileMenu with a bunch of file related commands. We create three Wx::MenuItems for this menu using the append method (the append method returns a menu item).

The append method takes three parameters. The first parameter is the ID of the menu item. We’ve used the standard ID’s for New, Open and Save. The second parameter takes a string for the text to appear on the menu item (the "\tCTRL + N" part is for the shortcut).
Lastly, the third parameter is the “help message” text which will appear if a status bar is present (optional).

    fileMenu = Wx::Menu.new
    newFileItem  = fileMenu.append(Wx::ID_NEW,  "&New\tCTRL+N",  'Create New File')
    openFileItem = fileMenu.append(Wx::ID_OPEN, "&Open\tCTRL+O", 'Open File')
    saveFileItem = fileMenu.append(Wx::ID_SAVE, "&Save\tCTRL+S", 'Save File')

Next we connect our menu items to the Wx::EVT_MENU event and the appropriate methods which we want called.

To make things easier, just remember the first parameter will always be the Wx::MenuItem (or it's ID) we are connecting and the second will be the method (or a block) we want called when the menu item is clicked.

    evt_menu(newFileItem, :new_file)
    evt_menu(openFileItem, :open_file)
    evt_menu(saveFileItem, :save_file)

Lastly, we append the File Wx::Menu instance to the [Wx::MenuBar](https://mcorino.github.io/wxRuby3/Wx/MenuBar.html, then attach the Wx::MenuBar to the frame using set_menu_bar (it won’t appear in the window otherwise).

    menuBar.append(fileMenu, 'File')
    #----------------

    self.set_menu_bar(menuBar)

The output of the above code with the File menu opened:

screenshot1

Note: On most systems, using the proper ID’s will automatically insert proper images and shortcuts into the menu items.

Creating a Submenu

Here we will create a submenu, which is basically a menu within a menu.

All we have to do is create a new Wx::Menu, add some items to it, and then use the append_sub_menu method on our parent menu. The append_sub_menu method takes two parameters, the submenu to be appended, and the name of the submenu.

require 'wx'

class MyWindow < Wx::Frame
  def initialize(title)
    super(nil, title: title)
    @panel = Wx::Panel.new(self)

    #----------------
    menuBar = Wx::MenuBar.new

    fileMenu = Wx::Menu.new
    newFileItem  = fileMenu.append(Wx::ID_NEW,  "&New\tCTRL+N",  'Create New File')
    openFileItem = fileMenu.append(Wx::ID_OPEN, "&Open\tCTRL+O", 'Open File')
    saveFileItem = fileMenu.append(Wx::ID_SAVE, "&Save\tCTRL+S", 'Save File')
    
    subMenu = Wx::Menu.new
    subMenu.append(Wx::ID_ANY, 'Recent Files', 'View Recent Files')
    subMenu.append(Wx::ID_ANY, 'Import File', 'Import external file')
    subMenu.append(Wx::ID_ANY, 'Export File')

    fileMenu.append_sub_menu(subMenu, 'File Options')

    menuBar.append(fileMenu, 'File')
    #----------------

    self.set_menu_bar(menuBar)
    
    centre
  end
  
end

Wx::App.run do
  window = MyWindow.new("wxRuby MenuBar Guide")
  window.show
end

We’ve used the default ID Wx::ID_ANY because there are no standard ID’s which are available for making these new menu items.

The output with the sub menu opened:

screenshot2

Appending other Items

In this example code we make some small changes. Instead of using append we use append_check_item, append_radio_item and append_separator, which will add a Wx::CheckBox, a Wx::RadioButton and a separator line respectively.

The syntax for append_check_item and append_radio_item is identical to that of append, whereas append_separator expects no parameters.

require 'wx'

class MyWindow < Wx::Frame
  def initialize(title)
    super(nil, title: title)
    @panel = Wx::Panel.new(self)

    #----------------
    menuBar = Wx::MenuBar.new

    fileMenu = Wx::Menu.new
    newFileItem  = fileMenu.append(Wx::ID_NEW,  "&New\tCTRL+N",  'Create New File')
    openFileItem = fileMenu.append(Wx::ID_OPEN, "&Open\tCTRL+O", 'Open File')
    saveFileItem = fileMenu.append(Wx::ID_SAVE, "&Save\tCTRL+S", 'Save File')
    
    subMenu = Wx::Menu.new
    subMenu.append_check_item(Wx::ID_ANY, 'Auto Save', 'Auto Save every 5 mins')
    subMenu.append_check_item(Wx::ID_ANY, 'Dark Mode', 'Enable Dark Theme')
    subMenu.append_check_item(Wx::ID_ANY, 'Enlarge Text', 'Increase Text Size')
    subMenu.append_separator
    subMenu2 = Wx::Menu.new
    subMenu2.append_radio_item(Wx::ID_ANY, 'Auto Save every 5 mins')
    subMenu2.append_radio_item(Wx::ID_ANY, 'Auto Save every 10 mins')
    subMenu2.append_radio_item(Wx::ID_ANY, 'Auto Save every 15 mins')

    subMenu.append_sub_menu(subMenu2, 'Auto Save')
    
    fileMenu.append_sub_menu(subMenu, 'Project Options')

    menuBar.append(fileMenu, 'File')
    #----------------

    self.set_menu_bar(menuBar)
    
    centre
  end
  
end

Wx::App.run do
  window = MyWindow.new("wxRuby MenuBar Guide")
  window.show
end

The output with the full menu opened:

screenshot3

Using MenuItem

Besides the Wx::Menu and Wx::MenuBar classes, we also have Wx::MenuItem. Normally we do not need to explicitly define one of these, as the append... methods return a Wx::MenuItem object. If you wish to create the Wx::MenuItem separately though, the below example will show you how (we also use the set_bitmap method to attach an alternate bitmap image).

require 'wx'

class MyWindow < Wx::Frame
  def initialize(title)
    super(nil, title: title)
    @panel = Wx::Panel.new(self)

    #----------------
    menuBar = Wx::MenuBar.new

    fileMenu = Wx::Menu.new
    exitItem = Wx::MenuItem.new(fileMenu, Wx::ID_EXIT, "&Quit\tCtrl+Q")
    exitItem.set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_CLOSE, Wx::ART_MENU))
    fileMenu.append(exitItem)

    evt_menu(exitItem, :on_quit)

    menuBar.append(fileMenu, 'File')
    #----------------

    self.set_menu_bar(menuBar)
    
    centre
  end
  
  def on_quit(_)
    puts 'Exit Window'
    close
  end
  
end

Wx::App.run do
  window = MyWindow.new("wxRuby MenuBar Guide")
  window.show
end

The output:

screenshot4

Menu Methods

A list of useful methods which can be used on the Wx::Menu objects.

Method Description
append(id, label, help, kind) Appends a menu item to the menu.
append_check_item(id, label, help) Appends a CheckBox Item to the menu.
append_radio_item(id, label, help) Appends a RadioButton Item to the menu
append_separator Appends a separator to the menu
append_sub_menu(menu, label, help) Appends another menu as a submenu.
break_ Adds a break into the menu, causing the next menu item to appear in a new column.
delete(id) Deletes the menu item with the specified ID.
enable(id, enable) Enables/Disables the menu item with the specified ID.
get_label(id) Returns the string value of the text of the menu item with the specified ID.
insert(pos, menu_item) Inserts an item at the specified index (similar variants exist for other items, like insert_check_item)
set_label(id, label) Sets the label of the menu item with the specified ID.

MenuBar Methods

A list of useful methods which can be used on the MenuBar widget.

Method Description
enable_top(pos, enable) Enables/Disables the menu at the given index.
get_menu(pos) Returns the menu at the given index.
get_menu_count Returns the number of menus in the menu bar
insert(pos, menu, title) Inserts a menu item at the given index, with the specified name (title).
Clone this wiki locally