解决 fyne 中文乱码问题

最近尝试使用 fyne 做一些简单的桌面应用,首先遇到的是中文乱码问题,目前主要有两种方案:
1. 将字体文件打包成 go 文件;
2. 使用 ENV 环境变量。

方案一:将字体打包成 go 文件

将字体生成 Go 文件

在安装了 fyne 工具后, 使用 fyne bundle --package xtheme ./fonts/SourceHanSerifSC-VF.ttf > ./app/xtheme/font.go : 将字体文件 ./fonts/SourceHanSerifSC-VF.ttf 打包到 ./app/xtheme/font.go 文件中,导出的包名为 xtheme

生成出的 font.go 文件格式如下:

// auto-generated
// Code generated by '$ fyne bundle'. DO NOT EDIT.

package xtheme

import "fyne.io/fyne/v2"

var resourceSourceHanSerifSCVFTtf = &fyne.StaticResource{
	StaticName: "SourceHanSerifSC-VF.ttf",
	StaticContent: []byte("\x00\x01..."),
	}

新建自定义主题文件

package xtheme

import (
	"image/color"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/theme"
)

type XTheme struct {
	fyne.Theme
}

func (*XTheme) Font(s fyne.TextStyle) fyne.Resource {
	return resourceSourceHanSerifSCVFTtf
}

func (m *XTheme) Size(name fyne.ThemeSizeName) float32 {
	return theme.DefaultTheme().Size(name)
}

func (m XTheme) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.Color {
	return theme.DefaultTheme().Color(name, variant)
}

func (m XTheme) Icon(name fyne.ThemeIconName) fyne.Resource {
	return theme.DefaultTheme().Icon(name)
}

应用自定义的主题文件

在应用中使用 SetTheme() 方法设置自定义的主题。

a := app.New()
a.Settings().SetTheme(&xtheme.XTheme{})

方案二:使用 ENV 环境变量

使用 github.com/flopp/go-findfont 这个库来通过环境变量查找字体。

import (
	"github.com/flopp/go-findfont"
	"github.com/golang/freetype/truetype"
)

func main(){
  fontFilePath := "./fonts/SourceHanSerifSC-VF.ttf" //
	fontPath, e := findfont.Find(fontFilePath)
	if e != nil {
		panic(e)
	}
	fmt.Printf("Found 'fontFile' in '%s'\n", fontPath)
	fontData, e := os.ReadFile(fontPath)
	if e != nil {
		panic(e)
	}
	_, e = truetype.Parse(fontData)
	if e != nil {
		panic(e)
	}
	os.Setenv("FYNE_FONT", fontPath)
	os.Setenv("FYNE_FONT_MONOSPACE", fontPath) // 注意:如果不设置这个环境变量会导致 widget.TextGrid 中的中文乱码

}

关于 TextGrid 组件的中文乱码问题:

在网上查到的设置环境变量的方式基本都是只设置了 FYNE_FONT_MONOSPACE 这个环境变量,
设置后 widget.TextGrid 组件内的中文仍然是乱码(其它组件内的中文能正常显示),并且通过打包字体文件到 go 文件的方式也不会对 widget.TextGrid 生效,
直到设置了 FYNE_FONT_MONOSPACE 环境变量后才解决了 TextGrid 组件的中文乱码问题。