起因
当前版本的 fyne 对中文支持不是很友好,尝试一段代码调用 fyne 来展示中文,效果如图:
代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package main
import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/widget" )
func main() { a := app.New() w := a.NewWindow("font") w.Resize(fyne.NewSize(300, 200)) w.SetContent( fyne.NewContainerWithLayout( layout.NewVBoxLayout(), layout.NewSpacer(), widget.NewLabel("撒旦撒旦"), widget.NewLabel("委屈额为"), widget.NewButton("请问犬瘟热第三方", func() { dialog.ShowInformation("非官方的", "从v风格化风格化", w) }), layout.NewSpacer(), ), ) w.ShowAndRun() }
|
现在想要 fyne 支持中文需要详细阅读官方文档(Text | Develop using Fyne)才能够得到答案。
fyne 的中文支持
文档中给出了两种方案:
- 使用环境变量
FYNE_FONT
指定 .ttf
类型字体,参见:Text | Develop using Fyne
- 捆绑字体文件(即自定义主题),参见:Creating a Custom Theme | Develop using Fyne
使用环境变量 FYNE_FONT
使用 fyne 内置的主题时,如果环境变量指定了字体文件,则可以将其用作字体。
Windows下指定环境变量
Windows 下通过设置环境变量 FYNE_FONT
为当前系统所支持的中文字体,例如 华文隶书 常规
字体,通过右键属性的方式得到字体名字:
然后设置环境变量:
Linux 与其它Unix操作系统指定环境变量
1
| FYNE_FONT=STLITI.TTF go run main.go
|
运行代码就能实现中文内容的显示了。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package main
import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/widget" )
func main() { a := app.New() w := a.NewWindow("font") w.Resize(fyne.NewSize(300, 200)) w.SetContent( fyne.NewContainerWithLayout( layout.NewVBoxLayout(), layout.NewSpacer(), widget.NewLabel("撒旦撒旦"), widget.NewLabel("委屈额为"), widget.NewButton("请问犬瘟热第三方", func() { dialog.ShowInformation("非官方的", "从v风格化风格化", w) }), layout.NewSpacer(), ), ) w.ShowAndRun() }
|
环境变量方式的缺点
虽然看起来还不错,但是这种方式在分发编译后的程序时会出现许多问题。
捆绑字体文件(自定义主题)
fyne提供了默认的主题,由于主题的可设置项包括了字体,于是可以通过自定义主题来使用任何的字体。
自定义主题可以通过实现主题接口来得到。
字体与 go 代码的捆绑
例如将字体 常规体
和 粗体
进行绑定。
命令为:
1 2
| fyne bundle STLITI.ttf > bundle.go fyne bundle -append STLITI-bold.ttf >> bundle.go
|
fyne bundle
命令
在 GUI 应用程序中,想要使用图像作为按钮的图标。 如果要分发应用程序就可以将资源文件(如图像文件)合并为单个二进制文件。
Fyne 为此提供了执行此操作的机制和有用的命令。
fyne bundle
通过使用命令,将资源文件(如图像)转换为 Fyne 可以处理的数据(具有字节原始数据的结构)。
具体可以参考:https://github.com/fyne-io/fyne/tree/master/cmd/fyne
定义主题Struct
定义想用使用的主题 struct
名称,并且实现 fyne.Theme
接口。
其中 Font
请按照业务逻辑进行处理即可。
1 2 3 4 5 6
| type Theme interface { Color(ThemeColorName, ThemeVariant) color.Color Font(TextStyle) Resource Icon(ThemeIconName) Resource Size(ThemeSizeName) float32 }
|
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package main
import ( "image/color"
"fyne.io/fyne/v2" "fyne.io/fyne/v2/theme" )
type Biu struct{}
func (b Biu) Font(s fyne.TextStyle) fyne.Resource { if s.Monospace { return theme.DefaultTheme().Font(s) } if s.Bold { if s.Italic { return theme.DefaultTheme().Font(s) } return resourceSTLITITTF } if s.Italic { return theme.DefaultTheme().Font(s) } return resourceSTLITITTF }
func (b Biu) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.Color { return theme.DefaultTheme().Color(name, variant) }
func (b Biu) Icon(name fyne.ThemeIconName) fyne.Resource { return theme.DefaultTheme().Icon(name) }
func (b Biu) Size(name fyne.ThemeSizeName) float32 { return theme.DefaultTheme().Size(name) }
|
使用自定义主题
通过 fyne.App
的 Settings().SetTheme()
方法实现,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package main
import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/widget" )
func main() { a := app.New() w := a.NewWindow("font") a.Settings().SetTheme(&Biu{}) w.Resize(fyne.NewSize(300, 200)) w.SetContent( fyne.NewContainerWithLayout( layout.NewVBoxLayout(), layout.NewSpacer(), widget.NewLabel("撒旦撒旦"), widget.NewLabel("委屈额为"), widget.NewButton("请问犬瘟热第三方", func() { dialog.ShowInformation("非官方的", "从v风格化风格化", w) }), layout.NewSpacer(), ), ) w.ShowAndRun() }
|
其中的 a.Settings().SetTheme(&Biu{})
就是具体的调用方式,运行结果为:
完整代码下载
参考资料