Skip to content

Ruby Tk Guide

Ruby/Tk provides bindings for the Tk GUI toolkit, allowing Ruby developers to create graphical user interfaces. Tk is a mature, cross-platform toolkit that has been part of Tcl and later made available to other languages like Perl, Python, and Ruby. The tk library is included in Ruby’s standard library, but you need to have the underlying Tcl/Tk libraries installed on your system.

While Tk is available and functional, its usage in new Ruby desktop applications has declined in favor of web-based UIs, or other GUI libraries offering more modern aesthetics. However, for simple cross-platform GUIs or for maintaining legacy applications, Ruby/Tk can still be a viable option.

The basic component of a Tk-based application is called a widget (e.g., button, label, text box). Widgets are arranged hierarchically within a root window. Modern Tk usage often involves Tk Themed Widgets (Tk::Tile) for a more native look and feel.

The Ruby tk gem itself is part of the standard library (for older Rubies) or can be installed via gem install tk (for newer Rubies where it was separated). However, you must have the Tcl/Tk libraries installed on your system first.

  • Windows: You might need to install a Tcl/Tk distribution like ActiveTcl from ActiveState.
  • macOS: Tcl/Tk is often pre-installed or can be installed via package managers like Homebrew (brew install tcl-tk).
  • Linux: Tcl/Tk can usually be installed via your distribution’s package manager (e.g., sudo apt-get install tk tcl tk-dev tcl-dev on Debian/Ubuntu, or sudo yum install tcl tk tcl-devel tk-devel on Fedora/CentOS).

Ensure your Ruby installation was compiled with Tk support or that the tk gem can find the Tcl/Tk libraries.

A typical Ruby/Tk program involves: creating a root window (TkRoot), adding widgets to it, arranging them using a geometry manager (pack, grid, or place), binding events, and starting the Tk main event loop (Tk.mainloop).

The traditional “Hello, World!” example:

#!/usr/bin/env ruby
require 'tk'
# Create the root window
root = TkRoot.new { title "Hello, Tk!" }
# Create a label widget as a child of the root window
label = TkLabel.new(root) do
text 'Hello, World!'
foreground 'blue'
font TkFont.new(family: 'Helvetica', size: 16, weight: 'bold')
pack(padx: 20, pady: 20, side: 'left') # Use pack geometry manager
end
# Create a button widget
count = 0
button = TkButton.new(root) do
text 'Click Me!'
command proc {
count += 1
label.text "Clicked #{count} times!"
}
pack(padx: 10, pady: 10, side: 'right')
end
# Start the Tk event loop
Tk.mainloop

If you run this script, it will produce a small window titled “Hello, Tk!”. Inside, on the left, you’ll see the text “Hello, World!” in blue, bold Helvetica font. On the right, there will be a button labeled “Click Me!”. Clicking the button will update the label’s text to show how many times it has been clicked.

Ruby/Tk provides classes for various standard widgets. Many of these have themed counterparts in the Tk::Tile namespace for a more modern look.

  • TkRoot: The main top-level window.
  • TkFrame (Tk::Tile::Frame): A container widget to group other widgets.
  • TkButton (Tk::Tile::Button): A standard button.
  • TkLabel (Tk::Tile::Label): Displays text or an image.
  • TkEntry (Tk::Tile::Entry): A single-line text input field.
  • TkText: A multi-line text input and display area.
  • TkCheckbutton (Tk::Tile::Checkbutton): A checkable button.
  • TkRadioButton (Tk::Tile::Radiobutton): Mutually exclusive option buttons.
  • TkListbox: A list of selectable text items.
  • TkComboBox (Tk::Tile::Combobox): A drop-down list combined with an entry field.
  • TkMenu, TkMenubutton: For creating menus.
  • TkScrollbar (Tk::Tile::Scrollbar): For scrolling content.
  • TkCanvas: A drawing area for shapes, lines, text, and images.
  • TkScale (Tk::Tile::Scale): A slider-like widget for selecting a numerical value.
  • TkProgressbar (Tk::Tile::Progressbar): To display progress of a task.
  • TkToplevel: For creating additional top-level windows (dialogs, etc.).
  • Tk::MessageBox: For standard dialogs (info, warning, error, yes/no questions).

It is generally recommended to use Tk::Tile widgets where available for better visual integration with the host operating system.

Widgets have numerous configuration options (set during creation or later with configure) that control their appearance and behavior. Options are typically passed as a hash or key-value pairs.

Common options include: text: Text to display. textvariable: A TkVariable to link widget text to a Ruby variable. font: Font specification. foreground (or fg): Text color. background (or bg): Background color. width, height: Desired size (meaning depends on widget). state: normal, disabled, readonly. command: A Proc or block to execute (e.g., on button click). anchor: How content is positioned within the widget (e.g., n, s, e, w, center). relief: Border style (raised, sunken, flat, ridge, groove). borderwidth: Border width. padx, pady: Internal padding around the widget’s content.

Example: Using configure and cget

my_button = TkButton.new(root) { text 'Initial' }
my_button.pack
# Configure an option
my_button.configure(text: 'Updated Text', foreground: 'red')
# Get an option's value
current_text = my_button.cget(:text)
puts "Button text is: #{current_text}" #=> Updated Text
# Get all options as a hash
all_options = my_button.configure
# puts all_options[:foreground].inspect

Geometry managers control the size and position of widgets within their parent container (master).

  • pack: Arranges widgets along the edges of a cavity or in remaining space. Simple for basic layouts. Options: side (top, bottom, left, right), fill (x, y, both), expand (boolean), padx, pady (external padding).
  • grid: Arranges widgets in a table-like grid of rows and columns. Powerful for complex layouts. Options: row, column, rowspan, columnspan, sticky (how widget sticks to cell edges, e.g., nsew), padx, pady.
  • place: Allows explicit positioning and sizing (absolute or relative). Less commonly used for dynamic layouts as it can be harder to manage resizing.

You typically choose one geometry manager per container. Mixing them in the same master widget can lead to issues.

Tk applications are event-driven. Events include mouse clicks, key presses, window resizing, etc. You can bind Ruby code (a Proc or block) to specific events on widgets using the bind method.

entry_widget = TkEntry.new(root).pack
# Bind to <KeyPress-Return> (Enter key)
entry_widget.bind('KeyPress-Return') do
puts "Enter pressed! Entry content: #{entry_widget.value}"
end
# Bind to mouse enter/leave events
entry_widget.bind('Enter') { entry_widget.background 'lightyellow' }
entry_widget.bind('Leave') { entry_widget.background 'white' }
# Event patterns can include modifiers: Control, Shift, Alt, Meta, Button1, etc.
# Example: 'Control-Shift-ButtonPress-1' (Ctrl+Shift+Left Click)

Many widgets also have a command option (like TkButton) for a primary action, which is a simpler way to handle common events.

Event PatternDescription
ButtonPress-N (or N)Mouse button N pressed (1=left, 2=middle, 3=right).
ButtonRelease-NMouse button N released.
Double-ButtonPress-N (or Double-N)Mouse button N double-clicked.
MotionMouse moved while a button is pressed (drag).
EnterMouse pointer entered the widget.
LeaveMouse pointer left the widget.
KeyPress (or Key)A key was pressed. Can specify a key: KeyPress-A, KeyPress-Return, KeyPress-F1.
KeyReleaseA key was released.
FocusInWidget gained keyboard focus.
FocusOutWidget lost keyboard focus.
ConfigureWidget changed size or position.

Event binding blocks can receive an event object argument (often named ev) which contains details about the event (e.g., ev.x, ev.y for mouse coordinates, ev.keysym for key pressed).

Ruby/Tk is a large topic. To learn more:

  • The official Tk documentation (for Tcl) is often the most comprehensive resource for widget options and behavior, then map concepts to Ruby/Tk syntax.
  • Search for Ruby/Tk tutorials and examples online. Be mindful that some older resources might not cover Tk::Tile theming.
  • Experiment! The best way to learn GUI programming is by building small applications.

Consider exploring other GUI options for Ruby if modern look & feel or advanced features are critical, such as Glimmer (LibUI bindings), or approaches involving web technologies.