• Golang的GUI开发包fyne基本教程


    关于 Fyne
    Fyne 是使用 Go 语言编写的易于使用的 UI 工具包和应用程序 API。它旨在构建使用单个代码库在桌面和移动设备上运行的应用程序。

    当前的版本是 1.2,该版本增加了对 iOS 和 Android 设备的支持,并提供了编写自定义窗口小部件的更简单方法。我们现在正在朝 1.3 迈进,它将添加数据绑定和一些更高级的小部件,例如表和列表。

    使用条件
    要使用 Fyne 开发应用,您将需要 Go 1.12 或更高版本。

    设置好goproxy=https://goproxy.cn,采用go mod模式开发,可以自动下载依赖包。

    编译注意事项

    如果不带任何参数编译,fyne应用会先打开控制台窗口,然后才从控制台窗口打开应用。要取消启动时的控制台窗口,需要在编译时加入如下参数:-ldflags -H=windowsgui。如下:

    go build -ldflags -H=windowsgui main.go

    Helloworld示例:

     1     package main
     2 
     3     import "fyne.io/fyne/widget"
     4     import "fyne.io/fyne/app"
     5 
     6     func main() {
     7         app := app.New()
     8 
     9         w := app.NewWindow("Hello")
    10         w.SetContent(widget.NewVBox(
    11             widget.NewLabel("Hello Fyne!"),
    12             widget.NewButton("Quit", func() {
    13                 app.Quit()
    14             }),
    15         ))
    16 
    17         w.ShowAndRun()
    18     }

    运行效果:

     一个更复杂的示例:

     1 // Package main provides various examples of Fyne API capabilities
     2 package main
     3 
     4 import (
     5     "fmt"
     6     "net/url"
     7 
     8     "fyne.io/fyne"
     9     "fyne.io/fyne/app"
    10     "fyne.io/fyne/canvas"
    11     "fyne.io/fyne/cmd/fyne_demo/data"
    12     "fyne.io/fyne/cmd/fyne_demo/screens"
    13     "fyne.io/fyne/layout"
    14     "fyne.io/fyne/theme"
    15     "fyne.io/fyne/widget"
    16 )
    17 
    18 const preferenceCurrentTab = "currentTab"
    19 
    20 func parseURL(urlStr string) *url.URL {
    21     link, err := url.Parse(urlStr)
    22     if err != nil {
    23         fyne.LogError("Could not parse URL", err)
    24     }
    25 
    26     return link
    27 }
    28 
    29 func welcomeScreen(a fyne.App) fyne.CanvasObject {
    30     logo := canvas.NewImageFromResource(data.FyneScene)
    31     logo.SetMinSize(fyne.NewSize(228, 167))
    32 
    33     return widget.NewVBox(
    34         widget.NewLabelWithStyle("Welcome to the Fyne toolkit demo app", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
    35         layout.NewSpacer(),
    36         widget.NewHBox(layout.NewSpacer(), logo, layout.NewSpacer()),
    37 
    38         widget.NewHBox(layout.NewSpacer(),
    39             widget.NewHyperlink("fyne.io", parseURL("https://fyne.io/")),
    40             widget.NewLabel("-"),
    41             widget.NewHyperlink("documentation", parseURL("https://fyne.io/develop/")),
    42             widget.NewLabel("-"),
    43             widget.NewHyperlink("sponsor", parseURL("https://github.com/sponsors/fyne-io")),
    44             layout.NewSpacer(),
    45         ),
    46         layout.NewSpacer(),
    47 
    48         widget.NewGroup("Theme",
    49             fyne.NewContainerWithLayout(layout.NewGridLayout(2),
    50                 widget.NewButton("Dark", func() {
    51                     a.Settings().SetTheme(theme.DarkTheme())
    52                 }),
    53                 widget.NewButton("Light", func() {
    54                     a.Settings().SetTheme(theme.LightTheme())
    55                 }),
    56             ),
    57         ),
    58     )
    59 }
    60 
    61 func main() {
    62     a := app.NewWithID("io.fyne.demo")
    63     a.SetIcon(theme.FyneLogo())
    64 
    65     w := a.NewWindow("Fyne Demo")
    66     w.SetMainMenu(fyne.NewMainMenu(fyne.NewMenu("File",
    67         fyne.NewMenuItem("New", func() { fmt.Println("Menu New") }),
    68         // a quit item will be appended to our first menu
    69     ), fyne.NewMenu("Edit",
    70         fyne.NewMenuItem("Cut", func() { fmt.Println("Menu Cut") }),
    71         fyne.NewMenuItem("Copy", func() { fmt.Println("Menu Copy") }),
    72         fyne.NewMenuItem("Paste", func() { fmt.Println("Menu Paste") }),
    73     )))
    74     w.SetMaster()
    75 
    76     tabs := widget.NewTabContainer(
    77         widget.NewTabItemWithIcon("Welcome", theme.HomeIcon(), welcomeScreen(a)),
    78         widget.NewTabItemWithIcon("Widgets", theme.ContentCopyIcon(), screens.WidgetScreen()),
    79         widget.NewTabItemWithIcon("Graphics", theme.DocumentCreateIcon(), screens.GraphicsScreen()),
    80         widget.NewTabItemWithIcon("Windows", theme.ViewFullScreenIcon(), screens.DialogScreen(w)),
    81         widget.NewTabItemWithIcon("Advanced", theme.SettingsIcon(), screens.AdvancedScreen(w)))
    82     tabs.SetTabLocation(widget.TabLocationLeading)
    83     tabs.SelectTabIndex(a.Preferences().Int(preferenceCurrentTab))
    84     w.SetContent(tabs)
    85 
    86     w.ShowAndRun()
    87     a.Preferences().SetInt(preferenceCurrentTab, tabs.CurrentTabIndex())
    88 }

    运行效果:

     

     中文支持

    首先,下载一个 TTF 格式的中文字库,可以下载思源字体的字库。需要注意的是,字库的格式必须是 TTF 的,否则会报错。

    然后添加一个环境变量 FYNE_FONT,指定下载好的字库文件:

    也可以用YaHeiConsolasHybrid.ttf字体,只要设置好FYNE_FONT变量就可以。
     
    下面是一个查询网络IP属主的示例:
     1 package main
     2 
     3 import (
     4     "fmt"
     5     "fyne.io/fyne"
     6     "fyne.io/fyne/app"
     7     "fyne.io/fyne/theme"
     8     "fyne.io/fyne/widget"
     9     "fyne.io/fyne/layout"
    10     "net/http"
    11     "io/ioutil"
    12     "encoding/json"
    13 )
    14 
    15 var ip = widget.NewLabel("")
    16 var position = widget.NewLabel("")
    17 var isp = widget.NewLabel("")
    18 
    19 type IpInfo struct {
    20     Code int `json:"code"`
    21     Message string `json:"msg"`
    22     Data `json:"data"`
    23 }
    24 
    25 type Data struct {
    26     IP string `json:"ip"`
    27     Position string `json:"pos"`
    28     Isp string `json:"isp"`
    29 }
    30 
    31 func main() {
    32     a := app.New()
    33     a.Settings().SetTheme(theme.LightTheme())
    34     w := a.NewWindow("Demo")
    35     w.Resize(fyne.NewSize(600, 500))
    36     w.SetContent(fyne.NewContainerWithLayout(layout.NewGridLayoutWithColumns(2), info(GetIpInfo("")), query()))
    37     w.ShowAndRun()
    38 }
    39 
    40 func GetIpInfo(ip string) string {
    41     if len(ip) == 0 {
    42         return ""
    43     }
    44 
    45     url := fmt.Sprintf("http://v1.alapi.cn/api/ip?ip=%s&format=json", ip)
    46 
    47     resp, err :=   http.Get(url)
    48     if err != nil {
    49         // handle error
    50     }
    51 
    52     defer resp.Body.Close()
    53     body, err := ioutil.ReadAll(resp.Body)
    54     if err != nil {
    55         // handle error
    56     }
    57 
    58     return string(body)
    59 }
    60 
    61 func query() fyne.CanvasObject {
    62     ip := widget.NewEntry()
    63     ip.SetPlaceHolder("Please input IP address")
    64 
    65     form := &widget.Form{
    66         OnSubmit: func() {
    67             info(GetIpInfo(ip.Text))
    68         },
    69     }
    70 
    71     form.Append("IP", ip)
    72     query := widget.NewGroup("Query", form)
    73     return widget.NewScrollContainer(query)
    74 }
    75 
    76 func info(response string) fyne.CanvasObject {
    77     var i IpInfo
    78     json.Unmarshal([]byte(response),&i)
    79 
    80     screen := widget.NewForm(
    81         &widget.FormItem{Text: "IP地址:", Widget: ip},
    82         &widget.FormItem{Text: "所属地:", Widget: position},
    83         &widget.FormItem{Text: "供应商:", Widget: isp},
    84     )
    85 
    86     ip.SetText(i.IP)
    87     position.SetText(i.Position)
    88     isp.SetText(i.Isp)
    89 
    90     info := widget.NewGroup("Info", screen)
    91     return widget.NewScrollContainer(info)
    92 }

    运行效果如下:

  • 相关阅读:
    手工卸载.Net写的win服务
    程序员素质面试题
    GridView数据导出功能
    使用EventLog类写系统日志
    HTML Response ContentType 大全
    用C#做短信CMPP2.0/3.0协议 支持扩展号支持物理网卡
    CYQ.Data 轻量数据层之路 使用篇MAction 数据查询 视频 E (二十二)
    CYQ.Data 轻量数据层之路 V2.0 震撼惊世 支持多数据库/内置Aop(二十五)
    MapXtreme 2005 GIS开发入门系列 索引
    CYQ.Data 轻量数据层之路 框架如何应对数据库变化
  • 原文地址:https://www.cnblogs.com/merrynuts/p/13050018.html
Copyright © 2020-2023  润新知