顾乔芝士网

持续更新的前后端开发技术栈

Fyne - Go语言的跨平台UI工具包

各主流的编程语言都有其特有的 UI 库,Go 语言也不甘落后。如果你不习惯用 Dart 或 Javascript 来开发跨平台的 GUI 应用,不妨来看看 Fyne,这个背靠强大易用的Go语言的UI工具库,兼具性能和开发效率,在桌面和移动端都能构建用户友好的应用。

简介

Fyne 是 fyne-io 组织在 Github 上开源的 Go 语言 UI 工具包,项目位于
https://github.com/fyne-io/fyne,目前版本为 v1.3.2。

Fyne 提供了简单的方式来开发美观、轻量和用户友好的原生应用,拥有大量性能高且方便使用的控件和布局。Fyne 专注于设计和可用性,控件能够充分满足用户对于交互的期待,并为开发者提供清晰的功能和接口。Fyne 易于安装,无须为各种复杂的依赖烦恼。而 Go 语言作为一个日渐流行的服务端语言,其较低的学习门槛和优秀的性能,使得 Fyne 具有更大的推广空间。目前,Fyne 已经拥有大量的使用案例,广受欢迎。

安装

Fyne 使用 Go 语言开发,需要 Go 1.12 或以上,使用 go get 安装:

go get fyne.io/fyne

同时,你还需要一个 C语言编译器来编译平台相关的图形驱动。对于 Windows 平台,Cygwin、TDM-GCC 和 MSYS2(MingW-w64)都可以使用。在 Linux 平台,则需安装对应平台的图形驱动,如在 Ubuntu / Debian 中可以使用命令

sudo apt-get install golang gcc libgl1-mesa-dev xorg-dev

想要开发 Android 应用,则需要安装 Android SDK 和 Android NDK。而想要挨罚 macOS 或 iOS 应用,则需要 Xcode 进行开发。

示例

Fyne 提供了使用函数。或是使用结构体这两套不同的接口风格,可以根据个人的编码喜好选择。我们来看 Fyne 的 Hello World 例子:

package main

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

func main() {
    a := app.New()
    w := a.NewWindow("Hello")

    hello := widget.NewLabel("Hello Fyne!")
    w.SetContent(widget.NewVBox(
        hello,
        widget.NewButton("Hi!", func() {
            hello.SetText("Welcome :)")
        }),
    ))

    w.ShowAndRun()
}

代码十分简洁明了。首先,通过 app.New() 创建一个应用实例,并新建一个标题为 Hello 的窗口。然后,使用 widget.NewLabel 来创建一个便签,并在窗口设置 垂直方向排列的vbox 布局,首先放置标签,然后再放置一个新建的按钮。按钮注册了一个点击事件的回调函数,在点击按钮时会把标签的文本更改为 Welcome。最后,运行并显示窗口。

直接运行代码:

go run hello.go

就会出现一个新的窗口,并显示带有一个标签和一个按钮的界面:

默认的主题是暗色调风格的,如果想要配置为明亮色调的主题,可以设置环境变量

FYNE_THEME=light

就能得到一个明亮色调主题的界面:

在上面的代码中,我们可以看到,控件的创建都是使用 New 之类的函数实现。Fyne 也提供了使用结构体的方式进行控件的创建,

package main

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

func main() {
	a := app.New()

	w := a.NewWindow("Hello")
	w.SetContent(&widget.Box{Children: []fyne.CanvasObject{
		&widget.Label{Text: "Hello Fyne!"},
		&widget.Button{Text: "Quit", OnTapped: func() {
			a.Quit()
		}},
	}})

	w.ShowAndRun()
}

在一些情况下,结构体方式的风格可能更为清晰,可自行选择。

Fyne 控件丰富,包括基本的按钮、输入框、表单、图标、进度条、选择框等。

package main

import (
    "log"

    "fyne.io/fyne/app"
    "fyne.io/fyne/widget"
)

func main() {
    myApp := app.New()
    myWindow := myApp.NewWindow("Form Widget")

    entry := widget.NewEntry()
    textArea := widget.NewMultiLineEntry()

    form := &widget.Form{
        Items: []*widget.FormItem{
            {"Entry", entry}},
        OnSubmit: func() {
            log.Println("Form submitted:", entry.Text)
            log.Println("multiline:", textArea.Text)
            myWindow.Close()
        },
    }

    form.Append("Text", textArea)

    myWindow.SetContent(form)
    myWindow.ShowAndRun()
}

Fyne 使用布局来控制控件的排列方式,包括 HBox(水平方向单行排列)、VBox(垂直方向单列排列)、Center(居中)、Grid(网格)、GridWrap(自适应的网格)、Border(各边外的剩余空间)和 Max(最大填充)。

Fyne 的窗口控制十分方便,充分利用了 Go 语言的协程特性,完成了窗口的异步渲染和控制:

package main

import (
	"time"

	"fyne.io/fyne"
	"fyne.io/fyne/app"
	"fyne.io/fyne/widget"
)

func main() {
	myApp := app.New()
	myWindow := myApp.NewWindow("Hello")
	myWindow.SetContent(widget.NewLabel("Hello"))

	go showAnother(myApp)
	myWindow.ShowAndRun()
}

func showAnother(a fyne.App) {
	time.Sleep(time.Second * 5)

	win := a.NewWindow("Shown later")
	win.SetContent(widget.NewLabel("5 seconds later"))
	win.Resize(fyne.NewSize(200, 200))
	win.Show()

	time.Sleep(time.Second * 2)
	win.Hide()
}

在本例中,我们在一个窗口中新建了另一个窗口并进行渲染显示,同时展示了包括控制大小、隐藏关闭等功能。

Fyne 还支持画布功能,可以在画布上进行自由渲染,实现更为复杂的图形应用:

package main

import (
    "fyne.io/fyne"
    "fyne.io/fyne/app"
    "fyne.io/fyne/canvas"
    "fyne.io/fyne/theme"
    "image/color"
    "time"
)

func main() {
    myApp := app.New()
    myWindow := myApp.NewWindow("Canvas")
    myCanvas := myWindow.Canvas()

    text := canvas.NewText("Text", color.White)
    text.TextStyle.Bold = true
    myCanvas.SetContent(text)
    go changeContent(myCanvas)

    myWindow.Resize(fyne.NewSize(100, 100))
    myWindow.ShowAndRun()
}

func changeContent(c fyne.Canvas) {
    time.Sleep(time.Second * 2)

    c.SetContent(canvas.NewRectangle(color.Black))

    time.Sleep(time.Second * 2)
    c.SetContent(canvas.NewLine(color.Gray{0x66}))

    time.Sleep(time.Second * 2)
    circle := canvas.NewCircle(color.White)
    circle.StrokeWidth = 4
    circle.StrokeColor = color.RGBA{0xff, 0x33, 0x33, 0xff}
    c.SetContent(circle)

    time.Sleep(time.Second * 2)
    c.SetContent(canvas.NewImageFromResource(theme.FyneLogo()))
}

更多

Fyne 的打包构建十分简单,安装 Fyne 配套的命令行工具

go get fyne.io/fyne/cmd/fyne

对应桌面端的应用,在确定好目标平台后就可以直接打包:

fyne package -os darwin -icon myapp.png
fyne package -os linux -icon myapp.png
fyne package -os windows -icon myapp.png

上述命令分别对应 macOS、Linux 和 Windows平台的构建,而 myapp.png 是应用的图标文件。对于 macOS 平台,生成 app 应用文件;对于 Linux 平台,生成一个 tag.gz 文件,解包后可以放到 use/local/ 中使用;对于 Windows 平台,直接生成 exe 文件,可以直接运行。

而对于移动端平台,同样十分简单。在配置好了相应的环境后,运行

fyne package -os android -appID com.example.myapp -icon mobileIcon.png
fyne package -os ios - appID com.example.myapp -icon mobileIcon.png

则可以分别构建出 Android 平台的 apk 文件和 iOS 平台的 app 文件。

总结

Fyne 作为一个 UI 工具包,依靠 Go 语言的优秀性能,尤其是 goroutine 协程的异步特性,实现了高性能、易开发的图形界面应用。Fyne 的使用和设计十分现代化,通过简单的命令行就能实现跨平台的开发和构建,安装方便,平台兼容性好。

Fyne 并未基于现有的 UI 库进行开发,而是直接使用不同平台的图形驱动实现,完成了对跨平台 UI 的抽象,底层代码值得研究。同时,Fyne 仍处于活跃开发阶段,不少功能仍待实现,有兴趣的开发者可持续关注项目。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言