Golang跨平台GUI框架Fyne的使用教程详解

2024-04-18 0 356
目录
  • 安装 fyne
  • 创建第一个应用
  • 布局和控件
    • 布局管理
    • 更多控件
  • Fyne 中的自定义
    • 自定义控件
    • 其他自定义
  • 数据绑定
    • 结语

      Go 官方没有提供标准的 GUI 框架,在 Go 实现的几个 GUI 库中,Fyne 算是最出色的,它有着简洁的API、支持跨平台能力,且高度可扩展。也就是说,Fyne 是可以用来开发 App 的。

      本文将尝试介绍下 Fyne,希望对大家快速上手这个 GUI 框架有所帮助。我最近产生了不少想法,其中有些是对 GUI 有要求的,就想着折腾用 Go 实现,而不是用那些已经很流行和成熟的 GUI 框架。

      在写这篇文章时,顺手搞了下它的中文版文档,文档查看www.poloxue.com/gofyne,希望对想继续深入这个框架的朋友有所帮助。

      Golang跨平台GUI框架Fyne的使用教程详解

      安装 fyne

      开始前,确保已成功安装 Go,如果是 MacOS X 系统,要确认安装了 xcode。

      如下使用go get命令安装 Fyne。

      $ mkdir hellofyne
      $ cd helloyfyne
      $ go mod init hellofyne
      $ go get fyne.io/fyne/v2@latest
      $ go install fyne.io/fyne/v2/cmd/fyne@latest

      如果想立刻查看 fyne 提供的演示案例,通过命令检查:

      $ go run fyne.io/fyne/v2/cmd/fyne_demo@latest

      Golang跨平台GUI框架Fyne的使用教程详解

      看起来,这里面的案例还是不够丰富的。

      安装工作到此就完成了。Fyne 对不同系统有不同依赖,如果安装过程中遇到问题,细节可查看官方提供的安装文档。

      创建第一个应用

      由于 Go 简洁的语法和 fyne 的设计,使用 fyne 创建一个 GUI 应用异常简单。

      以下是一个创建基础窗口的例子:

      package main

      import (
      \”fyne.io/fyne/v2/app\”
      \”fyne.io/fyne/v2/container\”
      \”fyne.io/fyne/v2/widget\”
      )

      func main() {
      a := app.New()
      w := a.NewWindow(\”Hello Fyne\”)
      w.SetContent(widget.NewLabel(\”Welcome to Fyne!\”))
      w.ShowAndRun()
      }

      这段代码创建了一个包含标签的窗口。

      通过app.New()初始化一个 Fyne 应用实例。然后,创建一个标题为 "Hello Fyne" 的窗口,并设置内容为包含 "Welcome to Fyne!" 文本标签。最后,通过w.ShowAndRun()显示窗口并启动应用的事件循环。

      fyne 中窗口的默认大小是其包含的内容决定,也可预置大小。

      如在创建窗口后,提供Resize重新调整大小。

      w.Resize(fyne.NewSize(100, 100))

      还有,一个 app 下可以有多个窗口的,示例代码:

      btn := widget.NewButton(\”Create a widnow\”, func() {
      w2 := a.NewWindow(\”Window 02\”)
      w2.Resize(fyne.NewSize(200, 200))
      w2.Show()
      })

      w.SetContent(btn)

      我们创建一个按钮,它的点击事件是创建一个新的窗口并显示。

      Golang跨平台GUI框架Fyne的使用教程详解

      布局和控件

      布局和控件是 GUI 应用程序设计中必不可少的两类组件。Fyne 提供了多种布局管理器和标准的 UI 控件,支持创建更复杂的界面。

      布局管理

      Fyne 中的布局的实现位于container包中。它提供了多种不同布局方式安排窗口中的元素。最基本的布局方式有HBox水平布局和VBox垂直布局。

      通过HBox创建水平布局的代码如下:

      w.SetContent(container.NewHBox(widget.NewButton(\”Left\”, func() {
      fmt.Println(\”Left button clicked\”)
      }), widget.NewButton(\”Right\”, func() {
      fmt.Println(\”Right button clicked\”)
      })))

      显示效果:

      Golang跨平台GUI框架Fyne的使用教程详解

      通过VBox创建垂直布局的例子。

      w.SetContent(container.NewVBox(widget.NewButton(\”Top\”, func() {
      fmt.Println(\”Top button clicked\”)
      }), widget.NewButton(\”Bottom\”, func() {
      fmt.Println(\”Bottom button clicked\”)
      })))

      显示效果:

      Golang跨平台GUI框架Fyne的使用教程详解

      Fyne 除了基础的水平(HBoxLayout)和垂直(VBoxLayout)布局,还提供了GridLayout、FormLayout甚至是混合布局CombinedLayout等高级布局方式。

      如GridLayout可以将元素均匀地分布在网格中,而FormLayout适用于创建表单,自动排列标签和字段。这些灵活的布局选项支持创建更复杂和功能丰富的GUI界面。

      官方文档中的布局列表查看:Layout List。

      更多控件

      前面的演示案例中,用到了两个控件:Label 和 Button,Fyne 还支持其他多种控件,它们都为于widget包中。

      我尝试在一份代码中展示出来,如下是常见控件一览:

      // 标签 Label
      label := widget.NewLabel(\”Label\”)
      // 按钮 Button
      button := widget.NewButton(\”Button\”, func() {})
      // 输入框 Entry
      entry := widget.NewEntry()
      entry.SetPlaceHolder(\”Entry\”)
      // 复选框 Check
      check := widget.NewCheck(\”Check\”, func(bool) {})
      // 单选框 Check
      radio := widget.NewRadioGroup([]string{\”Option 1\”, \”Option 2\”}, func(string) {})
      // 选择框
      selectEntry := widget.NewSelectEntry([]string{\”Option A\”, \”Option B\”}
      // 进度条
      progressBar := widget.NewProgressBar()
      // 滑块
      slider := widget.NewSlider(0, 100)
      // 组合框
      combo := widget.NewSelect([]string{\”Option A\”, \”Option B\”, \”Option C\”}, func(string) {})
      // 表单项
      formItem := widget.NewFormItem(\”FormItem\”, widget.NewEntry())
      form := widget.NewForm(formItem)
      // 手风琴
      accordion := widget.NewAccordion(widget.NewAccordionItem(\”Accordion\”, widget.NewLabel(\”Content\”)))
      // Tab 选择
      tabs := container.NewAppTabs(
      container.NewTabItem(\”Tab 1\”, widget.NewLabel(\”Content 1\”)),
      container.NewTabItem(\”Tab 2\”, widget.NewLabel(\”Content 2\”)),
      )

      // 弹出对话框示例按钮
      dialogButton := widget.NewButton(\”Show Dialog\”, func() {
      dialog.ShowInformation(\”Dialog\”, \”Dialog Content\”, w)
      })

      // 滚动布局
      content := container.NewVScroll(container.NewVBox(
      label, button, entry, check, radio, selectEntry, progressBar, slider,
      combo, form, accordion, tabs, dialogButton,
      ))
      w.SetContent(content)

      演示效果:

      Golang跨平台GUI框架Fyne的使用教程详解

      Fyne 中的自定义

      如果在实际项目中使用 Fyne,基本上是要使用 Fyne 的自定义能力。Fyne 提供了自定义控件、布局和主题等。

      自定义控件

      fyne 是支持实现自定义控件的,这涉及定义控件的绘制方法和布局逻辑。我们主要是实现两个接口:fyne.Widget和fyne.WidgetRenderer。

      fyne.Widget的定义如下所示:

      type Widget interface {
      CanvasObject
      CreateRenderer() WidgetRenderer
      }

      CreateRenderer方法返回的就是WiddgetRenderer,用于定义控件渲染和布局的逻辑。

      type WidgetRenderer interface {
      Destroy()
      Layout(Size)
      MinSize() Size
      Objects() []CanvasObject
      Refresh()
      }

      这样拆分的目标是为将了控件的逻辑和 UI 绘制分离开来,在Widget中专注于逻辑,而WidgetRenderer中专注于渲染布局。

      假设实现一个类似 Label 的控件,类型定义:

      type CustomLabel struct {
      widget.BaseWidget
      Text string
      }

      它继承了wiget.BaseWidget基本控件实现,Text就是要Label显示的文本。还要给给CustomLabel实现CreateRenderer方法。

      定义CustomLabel创建函数:

      func NewCustomLabel(text string) *CustomLabel {
      label := &CustomLabel{Text: text}
      label.ExtendBaseWidget(label)
      return label
      }

      customWidgetRenderer类型定义如下:

      type customWidgetRenderer struct {
      text *canvas.Text // 使用canvas.Text来绘制文本
      label *CustomLabel
      }

      实现CustomLabel的CreateRenderer方法。

      func (label *CustomLabel) CreateRenderer() fyne.WidgetRenderer {
      text := canvas.NewText(label.Text, theme.ForegroundColor())
      text.Alignment = fyne.TextAlignCenter

      return &customLabelRenderer{
      text: text,
      label: label,
      }
      }

      构建Renderer变量,使用canvas创建Text文本框,为适配主题使用主题配置前景色。还有,设置文本居中显示。

      而customLabelRenderer要实现WidgetRender接口定义的所有方法。

      func (r *customLabelRenderer) MinSize() fyne.Size {
      return r.text.MinSize()
      }

      func (r *customLabelRenderer) Layout(size fyne.Size) {
      r.text.Resize(size)
      }

      func (r *customLabelRenderer) Refresh() {
      r.text.Text = r.label.Text
      r.text.Color = theme.ForegroundColor() // 确保文本颜色更新
      r.text.Refresh()
      }

      func (r *customLabelRenderer) BackgroundColor() color.Color {
      return theme.BackgroundColor()
      }

      func (r *customLabelRenderer) Objects() []fyne.CanvasObject {
      return []fyne.CanvasObject{r.text}
      }

      func (r *customLabelRenderer) Destroy() {}

      在 main 函数中,尝试使用这个控件。

      a := app.New()
      w := a.NewWindow(\”Custom Label\”)

      w.SetContent(NewCustomLabel(\”Hello\”))
      w.ShowAndRun()

      显示的效果和 Label 控件是类似的。

      其他自定义

      其他自定义能力,如 Layout、Theme,我就不展开介绍。如果有机会,写点实际应用案例。如果基于案例介绍,会更有体悟吧。

      还有,Fyne 的官方文档写的挺易读的,可直接看它的文档。

      数据绑定

      Fyne 从 v2.0.0 开始支持数据绑定。它让控件和与数据实时连接,数据更改会自动反映在UI上,反之亦然。

      控件为了支持数据绑定能力,一般会提供如NewXXXWithData的接口。

      直接通过一个场景说明,目标是编辑输入框的内容,可同时立刻显示到 Label 上。

      核心代码如下所示:

      // 创建一个字符串绑定
      textBind := binding.NewString()

      // 创建一个 Entry,将其内容绑定到 textBind
      entry := widget.NewEntryWithData(textBind)

      // 创建一个 Label,也将其内容绑定到同一个 textBind
      label := widget.NewLabelWithData(textBind)

      // 使用容器放置 Entry 和 Label,以便它们都显示在窗口中
      content := container.NewVBox(entry, label)

      如上的代码,创建一个数据绑定类型的变量 textBind,并将其通过 NewWithData 将其绑定到两个控件上。

      显示效果,如下所示:

      Golang跨平台GUI框架Fyne的使用教程详解

      尝试让前面自定义的CustomLabel支持数据绑定能力。只要创建一个NewCustomLabelWithData构造函数。

      如下所示:

      func NewCustomLabelWithData(data binding.String) *CustomLabel {
      label := &CustomLabel{}
      label.ExtendBaseWidget(label)
      data.AddListener(binding.NewDataListener(func() {
      text, _ := data.Get()
      label.Text = text
      label.Refresh()
      }))
      return label
      }

      如上的代码中,其实就是通过data这个数据绑定类型变量监听数据变化,监听到变化后,更新空间内容并立刻刷新控件显示。

      Golang跨平台GUI框架Fyne的使用教程详解

      如上所示,我们这个自定义 Label 中的文本是居中显示的。

      数据绑定的核心是监听器模式(Observer pattern)。每个绑定对象内部维护了一个监听器列表,当数据变化时,这些监听器会被通知更新。

      在 Fyne 中,通过data.AddListner()将 UI 组件与数据绑定对象绑定时,实际上是在数据对象上注册了一个监听器,这个监听器会在数据变化时更新 UI 组件的状态。

      结语

      Fyne 是简单、强大和跨平台的 GUI 工具,使得用 GO 开发现代 GUI 应用多了一个优秀选择。随着对 Fyne 的深入,它能够更加灵活地构建出符合需求的应用。

      我喜欢用 Go 的原因,很重要的原因就是它的简洁性,很容易看到本质的东西,但又无需理解太复杂的编程概念。

      以上就是Golang跨平台GUI框架Fyne的使用教程详解的详细内容,更多关于Go Fyne的资料请关注悠久资源网其它相关文章!

      您可能感兴趣的文章:

      • 轻松入门:使用Golang开发跨平台GUI应用
      • Golang语言的跨平台UI工具包fyne使用详解
      • GolangWebView跨平台的桌面应用库的使用

      收藏 (0) 打赏

      感谢您的支持,我会继续努力的!

      打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
      点赞 (0)

      悠久资源 Golang Golang跨平台GUI框架Fyne的使用教程详解 https://www.u-9.cn/jiaoben/golang/187317.html

      常见问题

      相关文章

      发表评论
      暂无评论
      官方客服团队

      为您解决烦忧 - 24小时在线 专业服务