title: fyne 支持中文字体永久解决方案
date: 2021-09-07 14:32:00
toc: true
category:
- Golang
- fyne
tags: - Golang
- fyne
- 支持
- 中文
- 字体
- 永久
- 解决
- 方案
起因#
當前版本的 fyne 對中文支持不是很友好,嘗試一段代碼調用 fyne 來展示中文,效果如圖:
代碼為:
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 操作系統指定環境變量#
FYNE_FONT=STLITI.TTF go run main.go
運行代碼就能實現中文內容的顯示了。
代碼如下:
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 代碼的捆綁#
例如將字體 常規體
和 粗體
進行綁定。
命令為:
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
請按照業務邏輯進行處理即可。
type Theme interface {
Color(ThemeColorName, ThemeVariant) color.Color
Font(TextStyle) Resource
Icon(ThemeIconName) Resource
Size(ThemeSizeName) float32
}
代碼如下:
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()
方法實現,例如:
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{})
就是具體的調用方式,運行結果為: