Golang中使用Fyne编写的最简代码卡死问题

Golang中使用Fyne编写的最简代码卡死问题 [问题自行解决了,但我不知道为什么] 我对Go语言产生了兴趣,想看看如何构建最简单的桌面应用程序。我对它还不够熟悉,所以没能自己解决问题。在Windows 10上,无论是在命令行中还是在VSCode中执行代码,它都只是挂起,没有任何反应。而像“go mod init …”、“go mod tidy”这样的其他命令在相同的Windows或VSCode终端中运行得足够快。 我可以检查和修复什么,以使代码运行?

[Fyne识别了主要必要的依赖项] [代码本身]

[解决方案] 在我花了15分钟谷歌搜索和写这个问题时,我惊讶地看到我的应用程序终于启动了。现在再次执行“Go run”或“Go build”要快得多,大约1秒,而不是卡住。 不删除这个问题,以防其他一些沮丧的新手会搜索解决方案。在其他问题中,人们建议删除并再次执行“go mod init …”和“go mod tidy”,但这在我的情况下并没有帮助加快速度。我想知道发生了什么,以及这个难以置信的长延迟是什么。是否可能与某些C编译时间有关?


更多关于Golang中使用Fyne编写的最简代码卡死问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

如果使用了 -x 标志,Go 编译器会打印出它执行的命令。例如 go build -x .。这可以提供一些保证,表明构建正在进行中,而不仅仅是停滞了。

更多关于Golang中使用Fyne编写的最简代码卡死问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢您的回复。之前完全没有看到任何与编译相关的进度信息,甚至连简单的开始提示都没有——只有一片空白——这确实令人沮丧。不过,我注意到任务管理器里运行着一些与gcc相关的进程标题。这暗示着编译确实在后台运行,因为它占用了一些内存。

是否可能与某些C编译时间有关?

是的,这很可能就是原因。如果你曾使用 gotk4 编写一个简单的桌面应用程序,出于同样的原因,你也会有类似的体验。C编译器通常比Go编译器慢得多。

正如你所注意到的,后续的构建速度很快,因为构建好的fyne包已被缓存。所以,Go编译器只需要在你自己的应用程序包发生变化时重新编译它们。如果你使用“-a”标志进行构建(例如 go run -a .),那么缓存的包将被忽略,你将再次等待很长时间。缓存的包构建也特定于Go版本,因此如果你升级到新的Go版本,首次构建又会变慢。

问题中的延迟通常与Fyne首次运行时下载和编译依赖项有关。Fyne需要GLFW等C语言绑定,首次构建时会下载并编译这些C依赖,这在Windows上可能耗时较长。

以下是重现问题和验证解决方案的示例代码:

package main

import (
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/container"
    "fyne.io/fyne/v2/widget"
)

func main() {
    myApp := app.New()
    myWindow := myApp.NewWindow("Hello")
    
    hello := widget.NewLabel("Hello Fyne!")
    myWindow.SetContent(container.NewVBox(
        hello,
        widget.NewButton("Hi", func() {
            hello.SetText("Welcome :)")
        }),
    ))
    
    myWindow.ShowAndRun()
}

首次运行时的延迟包含以下步骤:

  1. 下载Fyne模块(如果未缓存)
  2. 下载GLFW源码(~5MB)
  3. 编译GLFW C代码为静态库
  4. 链接Go代码与C库

后续运行会直接使用已编译的缓存文件,因此速度恢复正常。缓存位置通常在:

  • Windows: %USERPROFILE%\AppData\Local\Fyne
  • Linux/macOS: ~/.cache/fyne

可以通过设置环境变量加速首次构建:

# Windows PowerShell
$env:FYNE_FONT="C:\Windows\Fonts\arial.ttf"
$env:FYNE_THEME="light"

# 然后运行
go run main.go

如果遇到持续卡死,可以检查:

// 添加超时检测
import "time"

func main() {
    done := make(chan bool)
    go func() {
        // 原有GUI代码
        done <- true
    }()
    
    select {
    case <-done:
    case <-time.After(30 * time.Second):
        panic("启动超时")
    }
}

这种首次构建延迟是正常的,特别是Windows上需要MSVC工具链编译C代码。后续构建会直接使用缓存,速度会显著提升。

回到顶部