Skip to content

Ruby Tk 指南

Ruby/Tk 提供了 Tk GUI 工具包的绑定,允许 Ruby 开发者创建图形用户界面(GUI)。Tk 是一个成熟的、跨平台的工具包,最初是 Tcl 的一部分,后来也提供给了 Perl、Python 和 Ruby 等其他语言。tk 库包含在 Ruby 的标准库中,但您需要在系统上安装底层 Tcl/Tk 库。

虽然 Tk 可用且功能正常,但在新的 Ruby 桌面应用程序中,其使用率有所下降,人们更倾向于基于 Web 的 UI 或其他提供更现代美学的 GUI 库。然而,对于简单的跨平台 GUI 或维护遗留应用程序,Ruby/Tk 仍然是一个可行的选择。

基于 Tk 的应用程序的基本组件称为控件(widget),例如按钮、标签、文本框。控件按层次结构排列在根窗口中。现代 Tk 通常使用 Tk Themed Widgets (Tk::Tile) 来实现更接近原生界面的观感。

Ruby tk gem 本身是标准库的一部分(对于旧版 Ruby)或可以通过 gem install tk 安装(对于已将其分离到 gem 的新版 Ruby)。但是,您必须首先在系统上安装 Tcl/Tk 库。

  • Windows: 您可能需要安装 ActiveState 的 ActiveTcl 等 Tcl/Tk 发行版。
  • macOS: Tcl/Tk 通常是预装的,或可以通过 Homebrew (brew install tcl-tk) 等包管理器安装。
  • Linux: Tcl/Tk 通常可以通过您的发行版包管理器安装(例如,在 Debian/Ubuntu 上使用 sudo apt-get install tk tcl tk-dev tcl-dev,或在 Fedora/CentOS 上使用 sudo yum install tcl tk tcl-devel tk-devel)。

确保您的 Ruby 安装已编译时包含 Tk 支持,或 tk gem 可以找到 Tcl/Tk 库。

典型的 Ruby/Tk 程序包括:创建根窗口(TkRoot)、向其中添加控件、使用几何管理器(pack、grid 或 place)排列它们、绑定事件以及启动 Tk 主事件循环(Tk.mainloop)。

传统的“Hello, World!”示例:

#!/usr/bin/env ruby
require 'tk'
# 创建根窗口
root = TkRoot.new { title "Hello, Tk!" }
# 创建一个标签控件作为根窗口的子控件
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') # 使用 pack 几何管理器
end
# 创建一个按钮控件
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
# 启动 Tk 事件循环
Tk.mainloop

如果您运行此脚本,它将产生一个标题为“Hello, Tk!”的小窗口。在窗口内部,左侧您将看到蓝色、粗体 Helvetica 字体的文本“Hello, World!”。右侧将有一个标有“Click Me!”的按钮。点击按钮将更新标签的文本,显示被点击的次数。

Ruby/Tk 提供了各种标准控件的类。其中许多在 Tk::Tile 命名空间中有主题化的对应类,以提供更现代的观感。

  • TkRoot:主顶级窗口。
  • TkFrame (Tk::Tile::Frame):用于组合其他控件的容器控件。
  • TkButton (Tk::Tile::Button):标准按钮。
  • TkLabel (Tk::Tile::Label):显示文本或图像。
  • TkEntry (Tk::Tile::Entry):单行文本输入字段。
  • TkText:多行文本输入和显示区域。
  • TkCheckbutton (Tk::Tile::Checkbutton):可选中的按钮。
  • TkRadioButton (Tk::Tile::Radiobutton):互斥的选项按钮。
  • TkListbox:可选择的文本项列表。
  • TkComboBox (Tk::Tile::Combobox):下拉列表与输入字段的组合。
  • TkMenu,TkMenubutton:用于创建菜单。
  • TkScrollbar (Tk::Tile::Scrollbar):用于滚动内容。
  • TkCanvas:用于绘制形状、线条、文本和图像的区域。
  • TkScale (Tk::Tile::Scale):用于选择数值的滑块式控件。
  • TkProgressbar (Tk::Tile::Progressbar):用于显示任务进度。
  • TkToplevel:用于创建额外的顶级窗口(对话框等)。
  • Tk::MessageBox:用于标准对话框(信息、警告、错误、是/否问题)。

通常建议使用 Tk::Tile 控件(如果可用),以便更好地与宿主操作系统进行视觉集成。

控件有许多配置选项(在创建时或之后使用 configure 设置),用于控制其外观和行为。选项通常以哈希或键值对的形式传递。

常见选项包括: text:要显示的文本。 textvariable:一个 TkVariable,用于将控件文本链接到 Ruby 变量。 font:字体规范。 foreground (或 fg):文本颜色。 background (或 bg):背景颜色。 width, height:期望的尺寸(含义取决于控件)。 state:normal(正常)、disabled(禁用)、readonly(只读)。 command:要执行的 Proc 或块(例如,在按钮点击时)。 anchor:内容在控件内的定位方式(例如,n、s、e、w、center)。 relief:边框样式(raised(凸起)、sunken(凹陷)、flat(平坦)、ridge(脊形)、groove(凹槽))。 borderwidth:边框宽度。 padx,pady:控件内容周围的内部填充。

示例:使用 configure 和 cget

my_button = TkButton.new(root) { text 'Initial' }
my_button.pack
# 配置一个选项
my_button.configure(text: 'Updated Text', foreground: 'red')
# 获取选项的值
current_text = my_button.cget(:text)
puts "Button text is: #{current_text}" #=> Updated Text
# 将所有选项作为哈希获取
all_options = my_button.configure
# puts all_options[:foreground].inspect

几何管理器控制控件在其父容器(master)中的大小和位置。

  • pack: 沿着父容器边缘或在剩余空间中排列控件。对于基本布局很简单。选项:side(top、bottom、left、right)、fill(x、y、both)、expand(布尔值)、padx、pady(外部填充)。
  • grid: 在表格状的行和列网格中排列控件。对于复杂布局很强大。选项:row、column、rowspan、columnspan、sticky(控件如何粘附到单元格边缘,例如 nsew)、padx、pady。
  • place: 允许显式定位和调整大小(绝对或相对)。对于动态布局较少使用,因为管理大小调整可能更困难。

通常每个容器选择一种几何管理器。在同一个父控件中混合使用它们可能会导致问题。

Tk 应用程序是事件驱动的。事件包括鼠标点击、按键、窗口大小调整等。您可以使用 bind 方法将 Ruby 代码(Proc 或块)绑定到控件上的特定事件。

entry_widget = TkEntry.new(root).pack
# 绑定到 <KeyPress-Return> (回车键)
entry_widget.bind('KeyPress-Return') do
puts "Enter pressed! Entry content: #{entry_widget.value}"
end
# 绑定鼠标进入/离开事件
entry_widget.bind('Enter') { entry_widget.background 'lightyellow' }
entry_widget.bind('Leave') { entry_widget.background 'white' }
# 事件模式可以包含修饰键:Control, Shift, Alt, Meta, Button1 等。
# 示例:'Control-Shift-ButtonPress-1' (Ctrl+Shift+左键单击)

许多控件也提供一个 command 选项(如 TkButton)用于主要操作,这是处理常见事件的更简单方式。

Event Pattern描述
ButtonPress-N (or N)鼠标按钮 N 被按下(1=左键,2=中键,3=右键)。
ButtonRelease-N鼠标按钮 N 被释放。
Double-ButtonPress-N (or Double-N)鼠标按钮 N 被双击。
Motion在按下按钮时移动鼠标(拖动)。
Enter鼠标指针进入控件。
Leave鼠标指针离开控件。
KeyPress (or Key)某个键被按下。可以指定键:KeyPress-A、KeyPress-Return、KeyPress-F1。
KeyRelease某个键被释放。
FocusIn控件获得键盘焦点。
FocusOut控件失去键盘焦点。
Configure控件改变了大小或位置。

事件绑定块可以接收一个事件对象参数(通常命名为 ev),其中包含有关事件的详细信息(例如,ev.x、ev.y 表示鼠标坐标,ev.keysym 表示按下的键)。

Ruby/Tk 是一个很大的主题。要了解更多信息:

  • Tk 官方文档(针对 Tcl)通常是关于控件选项和行为最全面的资源,然后将概念映射到 Ruby/Tk 语法。
  • 在线搜索 Ruby/Tk 教程和示例。请注意,一些较旧的资源可能未涵盖 Tk::Tile 主题化。
  • 实践!学习 GUI 编程的最佳方法是构建小型应用程序。

如果现代观感或高级功能至关重要,请考虑探索其他 Ruby GUI 选项,例如 Glimmer (LibUI 绑定),或涉及 Web 技术的方案。