mGTK 的 Hello World 程序展示了怎样的代码结构?

更新时间

mGTK 的 Hello World 程序是一个完整的 SML 程序,结构上分为“初始化 → 创建控件 → 连接信号 → 组装控件 → 显示 → 进入事件循环”六步。它使用 Moscow ML 编译器(页面同时说明 MLton 支持已接近就绪,pre-0.92 起已带 MLton 支持),运行在同时被 Moscow ML 和 GTK+ 支持的平台上,已知可在 Linux 和 Windows 上运行。下面按这个顺序拆解代码,并给出验证方法和常见卡点。

完整代码

fun hello _ = print "Hello World\n"

fun main () =
  let
    val _ = GtkBasis.init(CommandLine.name()::CommandLine.arguments())
    val window = Window.new Window.TOPLEVEL
    val button = Button.new_with_label "Hello World"
  in
    Signal.connect window (Widget.delete_event_sig (fn _ => false)) ;
    Signal.connect window (Widget.destroy_event_sig (fn _ => (GtkBasis.main_quit(); true))) ;
    Signal.connect button (Button.clicked_sig hello) ;
    Container.add window button ;
    Widget.show_all window ;
    GtkBasis.main()
  end

各部分在做什么

1. 初始化:GtkBasis.init

GtkBasis.init 接收命令行参数列表,这里用 CommandLine.name()::CommandLine.arguments() 把程序名和参数拼成列表传入。这是 GTK+ 类库的惯例:初始化时把命令行交给工具包处理。预期结果是 GTK+ 运行时完成初始化,之后才能创建控件。

2. 创建控件:Window.new 与 Button.new_with_label

  • Window.new Window.TOPLEVEL 创建一个顶层窗口。
  • Button.new_with_label "Hello World" 创建一个带文字标签的按钮。

两者都是“先创建对象、再单独配置”的风格,控件创建与事件绑定是分开的语句。

3. 连接信号:Signal.connect

三处 Signal.connect 分别处理三类事件:

信号 绑定对象 回调行为
Widget.delete_event_sig 窗口 返回 false,即不拦截删除事件,交给后续处理
Widget.destroy_event_sig 窗口 调用 GtkBasis.main_quit() 退出事件循环,返回 true
Button.clicked_sig 按钮 调用 hello,打印 Hello World

注意 hello 的类型是 'a -> unit(用 _ 忽略参数),正好匹配点击回调的签名。

4. 组装与显示:Container.add 与 Widget.show_all

Container.add window button 把按钮放进窗口;Widget.show_all window 递归显示窗口及其子控件。缺少 show_all 时窗口可能创建成功但内容不可见,这是初学者最常见的卡点之一。

5. 进入事件循环:GtkBasis.main()

GtkBasis.main() 阻塞运行,直到 main_quit 被调用。程序的实际交互(点击按钮、关闭窗口)都发生在这个循环里。

如何验证程序能跑通

  1. 确认环境:Moscow ML 与 GTK+ 均已安装,且平台在两者共同支持范围内(Linux 或 Windows 是页面明确提到的)。
  2. 编译并运行上述程序。
  3. 预期现象:出现一个含 “Hello World” 按钮的窗口;点击按钮,终端输出 Hello World;关闭窗口后程序退出。

常见卡点

  • 窗口空白:检查是否调用了 Widget.show_all。
  • 关闭窗口后进程不退出:检查 destroy_event_sig 回调里是否调用了 GtkBasis.main_quit()。
  • 点击无反应:确认 Signal.connect 绑定的信号与控件匹配(按钮用 Button.clicked_sig,窗口用 Widget.*_event_sig)。
  • 编译或链接失败:优先核对编译器与 GTK+ 的版本组合;页面说明当前主要支持 Moscow ML,MLton 支持在 pre-0.92 中才加入,旧版本上不要假设可用。

该示例来自 mGTK 项目主页,页面同时说明这是一个 pre-release,文档指引有限,遇到问题可联系作者。