跳转至

11 · 多窗口

单窗口使用 ui.Run(Program)。需要多个独立窗口、托盘或应用生命周期控制时,使用 ui.Application

概念

概念 说明
Application 多窗口宿主
WindowSpec 一个窗口的规格(key、初始化、Update、View、选项)
窗口 key 字符串身份,用于 Open / Close / SetTheme
Application.Open 返回 true 表示新窗口已启动;返回 false 表示同 key 的窗口已存在并被前置,或应用当前不接受新窗口

每个窗口有独立 Model 实例;初始化函数按实例执行,不要共享可变 Model。 使用 NewProgram 时,初始 Model 按值固定在 Program 中;如果 Model 含有 slice、map 或指针等引用类型,需要使用 Program.Init 在每次打开时创建新的值。

基本结构

func main() {
    application := ui.NewApplication()

    counter := ui.NewWindow("counter", ui.NewProgram(
        CounterModel{}, counterUpdate, counterView(application),
    ),
        ui.Title("Counter"),
        ui.Size(400, 300),
    )

    mainWin := ui.NewWindow("main", ui.NewProgram(
        MainModel{}, mainUpdate(application), mainView(application, counter),
    ),
        ui.Title("Main"),
        ui.Size(640, 480),
    )

    application.Run(mainWin)
}

需要初始命令、订阅或窗口状态消息时,把完整 Program 字面量传给 ui.NewWindow

打开与关闭

if application.Open(counterSpec) {
    // 新建并运行
} else {
    // 同 key 已存在并已前置,或应用当前不接受新窗口
}

application.Close("counter")

在主窗口按钮里:

ui.Button("open", ui.Text("打开计数器")).OnClick(func() {
    application.Open(counter)
})

主题与语言(按窗口)

application.SetTheme("main", ui.DarkTheme())
application.SetLanguage("main", ui.LanguageChinese)

在对应窗口的 Update 中根据消息调用(见 examples/multi_windows)。 不要在任意 goroutine 里直接改主题;走 Application API,以便在目标窗口事件循环上应用。

窗口状态

在 View 中:

state := ctx.WindowState()
// state.Size, state.Mode, state.Focused, ...

也可用 Program.WindowStateMessage 把配置变化转成 Msg。

窗口动作(最小化/最大化等)见示例中的 WindowAction* 用法。

注意

  1. key 唯一:同一 Application 内窗口 key 不要冲突。
  2. Model 独立:每个 Program.Init 应返回新的 Model;不要共享可变指针。
  3. 不要跨窗口直接改对方 Model;用消息、共享服务或 Application 协调。
  4. Cmd 的 context 随该窗口生命周期取消。

示例

go run ./examples/multi_windows

下一步