我跟随this tutorial人使用GIO,这是一个跨平台的图形用户界面库.我觉得代码应该更有条理,所以我想出了一个巧妙的解决方案,将创建窗口的各个阶段与其内容分开.基本上,我只是将教程中的概念重构为我更习惯的东西.

所以我有3个文件:

Main.go:

package main

import (
    "log"
    "os"

    "toucam/windows"

    "gioui.org/app"
    "gioui.org/op"
    "gioui.org/widget/material"
)

var ops op.Ops

func main() {
    go func() {
        // create new window
        w := app.NewWindow(
            app.Title("Egg Timer"),
            //app.Maximized.Option(),
        )

        if err := run(w); err != nil {
            log.Fatal(err)
        }
        os.Exit(0)
    }()
    app.Main()
}

func run(w *app.Window) error {
    theme := material.NewTheme()

    mw := windows.NewMainWindow(theme)

    for {
        switch e := w.NextEvent().(type) {
        case app.FrameEvent:
            mw.Layout(app.NewContext(&ops, e))
        case app.DestroyEvent:
            return e.Err
        }
    }
}

Windows/window.go:

package windows

import (
    "gioui.org/layout"
    "gioui.org/widget/material"
)

type window struct {
    title  string
    theme  *material.Theme
    Layout func(gtx layout.Context) layout.Dimensions
}

and windows/Main.go:

package windows

import (
    "gioui.org/layout"
    "gioui.org/widget"
    "gioui.org/widget/material"
)

var startButton widget.Clickable

func NewMainWindow(theme *material.Theme) window {
    mainWindow := window{
        title: "TOUCAM",
        theme: theme,
        Layout: func(gtx layout.Context) layout.Dimensions {
            //Window layout goes here
            return layout.Flex{
                Axis:    layout.Vertical,
                Spacing: layout.SpaceStart,
            }.Layout(gtx,
                layout.Rigid(
                    func(gtx layout.Context) layout.Dimensions {
                        btn := material.Button(theme, &startButton, "Start")
                        return btn.Layout(gtx)
                    },
                ),
            )
        },
    }

    return mainWindow
}

正如您所看到的,我try 做的是将给定窗口的 struct 隔离到它自己的文件中.结果是一个空的窗口.没有按钮.我不太确定为什么.

Here is a repo和您可以用来测试的确切代码.

有人能找出我做错了什么吗?

推荐答案

您错过了对e.Frame(&ops)的调用,这里是main.go中已修复的app.FrameEvent事件处理程序:

        case app.FrameEvent:
            mw.Layout(app.NewContext(&ops, e))
            e.Frame(&ops)

如第documentation条所述

Frame通过将图形操作从Ops绘制到窗口来完成FrameEvent.

因此,在您的情况下没有绘制按钮,因为绘制它的图形操作只创建了,但尚未执行(即这些操作从未应用于框架).

Go相关问答推荐

golang 的条件储存库

Go协议缓冲区导入问题

GORM没有从 struct 创建完整的表,如何修复?

Golang使用Run()执行的命令没有返回

在Golang中Mergesort的递归/并行实现中出现死锁

如何在v2 Go SDK中使用KeyConditionExpression查询AWS DynamoDb?

Cypher 查找(多个)最低 node

Prometheus 摘要分位数错误

如何将已知类型转换为指向switch 中类型参数的指针?

Go Programming Language书上的例子server2错了吗?

如何使用 sync.WaitGroup 来执行所有的 goroutine?

Gorm 在自定义字符串类型上返回 scanner 错误

如何使用 Go 代理状态为 OK 的预检请求?

获取不带类型参数的泛型 struct 的类型名称

在 Go GRPC 服务器流式拦截器上修改元数据

在 go 中将运行命令的标准输出发送到其标准输入

go 是否对 struct 使用空间填充之类的东西?

使用无服务器工作流 go sdk 时出现间歇性 JSON 解组错误

Golang 'defer' 导致发送(接收)API 响应延迟

(如何)我可以基于接口抽象地实现Stringer吗?