欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang跨平臺GUI框架Fyne的使用教程詳解

 更新時間:2024年03月07日 10:21:41   作者:波羅學  
Go 官方沒有提供標準的 GUI 框架,在 Go 實現的幾個 GUI 庫中,Fyne 算是最出色的,它有著簡潔的API、支持跨平臺能力,且高度可擴展,下面我們就來看看它的具體使用吧

Go 官方沒有提供標準的 GUI 框架,在 Go 實現的幾個 GUI 庫中,Fyne 算是最出色的,它有著簡潔的API、支持跨平臺能力,且高度可擴展。也就是說,Fyne 是可以用來開發(fā) App 的。

本文將嘗試介紹下 Fyne,希望對大家快速上手這個 GUI 框架有所幫助。我最近產生了不少想法,其中有些是對 GUI 有要求的,就想著折騰用 Go 實現,而不是用那些已經很流行和成熟的 GUI 框架。

在寫這篇文章時,順手搞了下它的中文版文檔,文檔查看 www.poloxue.com/gofyne,希望對想繼續(xù)深入這個框架的朋友有所幫助。

安裝 fyne

開始前,確保已成功安裝 Go,如果是 MacOS X 系統(tǒng),要確認安裝了 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

看起來,這里面的案例還是不夠豐富的。

安裝工作到此就完成了。Fyne 對不同系統(tǒng)有不同依賴,如果安裝過程中遇到問題,細節(jié)可查看官方提供的安裝文檔。

創(chuàng)建第一個應用

由于 Go 簡潔的語法和 fyne 的設計,使用 fyne 創(chuàng)建一個 GUI 應用異常簡單。

以下是一個創(chuàng)建基礎窗口的例子:

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()
}

這段代碼創(chuàng)建了一個包含標簽的窗口。

通過 app.New() 初始化一個 Fyne 應用實例。然后,創(chuàng)建一個標題為 "Hello Fyne" 的窗口,并設置內容為包含 "Welcome to Fyne!" 文本標簽。最后,通過w.ShowAndRun()顯示窗口并啟動應用的事件循環(huán)。

fyne 中窗口的默認大小是其包含的內容決定,也可預置大小。

如在創(chuàng)建窗口后,提供 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)

我們創(chuàng)建一個按鈕,它的點擊事件是創(chuàng)建一個新的窗口并顯示。

布局和控件

布局和控件是 GUI 應用程序設計中必不可少的兩類組件。Fyne 提供了多種布局管理器和標準的 UI 控件,支持創(chuàng)建更復雜的界面。

布局管理

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

通過 HBox 創(chuàng)建水平布局的代碼如下:

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

顯示效果:

通過 VBox 創(chuàng)建垂直布局的例子。

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

顯示效果:

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

如 GridLayout可以將元素均勻地分布在網格中,而FormLayout適用于創(chuàng)建表單,自動排列標簽和字段。這些靈活的布局選項支持創(chuàng)建更復雜和功能豐富的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)

演示效果:

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 創(chuàng)建函數:

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 創(chuàng)建 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 上。

核心代碼如下所示:

// 創(chuàng)建一個字符串綁定
textBind := binding.NewString()

// 創(chuàng)建一個 Entry,將其內容綁定到 textBind
entry := widget.NewEntryWithData(textBind)

// 創(chuàng)建一個 Label,也將其內容綁定到同一個 textBind
label := widget.NewLabelWithData(textBind)

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

如上的代碼,創(chuàng)建一個數據綁定類型的變量 textBind,并將其通過 NewWithData 將其綁定到兩個控件上。

顯示效果,如下所示:

嘗試讓前面自定義的 CustomLabel 支持數據綁定能力。只要創(chuàng)建一個 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 這個數據綁定類型變量監(jiān)聽數據變化,監(jiān)聽到變化后,更新空間內容并立刻刷新控件顯示。

如上所示,我們這個自定義 Label 中的文本是居中顯示的。

數據綁定的核心是監(jiān)聽器模式(Observer pattern)。每個綁定對象內部維護了一個監(jiān)聽器列表,當數據變化時,這些監(jiān)聽器會被通知更新。

在 Fyne 中,通過 data.AddListner() 將 UI 組件與數據綁定對象綁定時,實際上是在數據對象上注冊了一個監(jiān)聽器,這個監(jiān)聽器會在數據變化時更新 UI 組件的狀態(tài)。

結語

Fyne 是簡單、強大和跨平臺的 GUI 工具,使得用 GO 開發(fā)現代 GUI 應用多了一個優(yōu)秀選擇。隨著對 Fyne 的深入,它能夠更加靈活地構建出符合需求的應用。

我喜歡用 Go 的原因,很重要的原因就是它的簡潔性,很容易看到本質的東西,但又無需理解太復雜的編程概念。

以上就是Golang跨平臺GUI框架Fyne的使用教程詳解的詳細內容,更多關于Go Fyne的資料請關注腳本之家其它相關文章!

相關文章

  • golang利用pprof與go-torch如何做性能分析

    golang利用pprof與go-torch如何做性能分析

    這篇文章主要給大家介紹了關于golang利用pprof與go-torch如何做性能分析的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-07-07
  • Go語言實戰(zhàn)之實現均衡器功能

    Go語言實戰(zhàn)之實現均衡器功能

    這篇文章主要為大家詳細介紹了如何利用Golang?實現一個簡單的流浪均衡器,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-04-04
  • go實現服務優(yōu)雅關閉的示例

    go實現服務優(yōu)雅關閉的示例

    本文主要介紹了go實現服務優(yōu)雅關閉的示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • go mod 安裝依賴 unkown revision問題的解決方案

    go mod 安裝依賴 unkown revision問題的解決方案

    這篇文章主要介紹了go mod 安裝依賴 unkown revision問題的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Golang你一定要懂的連接池實現

    Golang你一定要懂的連接池實現

    這篇文章主要介紹了Golang你一定要懂的連接池實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • GoLang抽獎系統(tǒng)簡易實現流程

    GoLang抽獎系統(tǒng)簡易實現流程

    這篇文章主要介紹了GoLang抽獎系統(tǒng)實現流程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-12-12
  • 淺析Go語言中Channel的各種用法

    淺析Go語言中Channel的各種用法

    這篇文章主要帶大家一起來學習一下Go語言中的if語句,也就是大家口中的判斷語句。文中的示例代碼講解詳細,對我們學習Go語言有一定幫助,需要的可以參考一下
    2022-11-11
  • Go Time庫中時間和日期相關的操作方法整理

    Go Time庫中時間和日期相關的操作方法整理

    這篇文章主要為大家整理了Go語言中的time庫,包括時間、日期和時區(qū)等相關概念及使用方法,希望通過掌握這些知識,大家可以更好地處理時間、日期和時區(qū)相關的問題
    2023-08-08
  • go程序員日常開發(fā)效率神器匯總

    go程序員日常開發(fā)效率神器匯總

    這篇文章主要介紹了go程序員開發(fā)效率神器包含了go常用開發(fā)工具,go調試工具,go常用網站,golang常用庫,需要的朋友可以參考下
    2022-11-11
  • golang開發(fā)安裝go-torch火焰圖操作步驟

    golang開發(fā)安裝go-torch火焰圖操作步驟

    這篇文章主要為大家介紹了golang開發(fā)安裝go-torch火焰圖操作步驟
    2021-11-11

最新評論