• Go中GUI库fyne


    Go中GUI库fyne学习

    参考

    Fyne包结构划分

    fyne将功能划分到不同的子包中:

    • fyne.io/fyne:提供所有fyne应用程序代码共用的基础定义,包括数据类型和接口;
    • fyne.io/fyne/app:提供创建应用程序的 API;
    • fyne.io/fyne/canvas:提供Fyne使用的绘制 API;
    • fyne.io/fyne/dialog:提供对话框组件;
    • fyne.io/fyne/layout:提供多种界面布局;
    • fyne.io/fyne/widget:提供多种组件,fyne所有的窗体控件和交互元素都在这个子包中。

    使用-Demo

    快速使用

    package main
    
    import (
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/container"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Hello")
    	hello := widget.NewLabel("Hello Fyne!")
    	w.SetContent(container.NewVBox(
    		hello,
    		widget.NewButton("Hi!", func() {
    			hello.SetText("Welcome:")
    		}),
    	))
    
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述

    效果,当你点击Hi!点击按钮时上面的文字变为了Welcome:

    Canvas

    package main
    
    import (
    	"image/color"
    	"math/rand"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/canvas"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/theme"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Canvas")
    	rect := canvas.NewRectangle(color.White)
    
    	text := canvas.NewText("Hello Text", color.Black)
    	text.Alignment = fyne.TextAlignTrailing
    	text.TextStyle = fyne.TextStyle{Italic: true}
    
    	line := canvas.NewLine(color.Black)
    	line.StrokeWidth = 4
    	
        // 绘制LoGo图
    	image := canvas.NewImageFromResource(theme.FyneLogo())
    	image.FillMode = canvas.ImageFillOriginal
    
    	// 像素图
    	raster := canvas.NewRasterWithPixels(
    		func(_, _, w, h int) color.Color {
    			return color.RGBA{uint8(rand.Intn(255)),
    				uint8(rand.Intn(255)),
    				uint8(rand.Intn(255)), 0xff}
    		},
    	)
    
    	gradient := canvas.NewHorizontalGradient(color.White, color.Transparent)
    
    	container := fyne.NewContainerWithLayout(
    		layout.NewGridWrapLayout(fyne.NewSize(150, 150)),
    		rect, text, line, image, raster, gradient,
    	)
    
    	w.SetContent(container)
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    效果图

    在这里插入图片描述

    Widget

    窗体控件是一个Fyne应用程序的主要组成部分。它们能适配当前的主题,并且处理与用户的交互。

    Label

    Label(标签)是一个简单的空间,用于字符串的展示。

    package main
    
    import (
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Label")
    
    	l1 := widget.NewLabel("Name")
        // 可以识别转义字符
    	l2 := widget.NewLabel("Yu\nhandsome")
    
    	container := fyne.NewContainerWithLayout(layout.NewVBoxLayout(), l1, l2)
    	w.SetContent(container)
    	w.Resize(fyne.NewSize(150, 150))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    效果

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8KLvVuNf-1661592613756)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20220827135430414.png)]

    Button
    package main
    
    import (
    	"fmt"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/theme"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Button")
    
    	btn1 := widget.NewButton("text button", func() {
    		fmt.Println("btn1 button clicked")
    	})
    	btn2 := widget.NewButtonWithIcon("text button", theme.HomeIcon(), func() {
    		fmt.Println("Home")
    	})
    
    	container := fyne.NewContainerWithLayout(layout.NewVBoxLayout(), btn1, btn2)
    	w.SetContent(container)
    	w.Resize(fyne.NewSize(150, 150))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这个案例中我们创建两个按钮,两种共同之处是都需要传入按钮名称和按钮点击触发的执行函数。值得一提的是我们还可以加载外部的图标进行装饰。

    效果

    在这里插入图片描述

    Box
    package main
    
    import (
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Button")
    
    	content := widget.NewVBox(
    		widget.NewLabel("The top row of VBox"),
    		widget.NewHBox(
    			widget.NewLabel("Label 1"),
    			widget.NewLabel("Label 2"),
    		),
    	)
    
    	content.Append(widget.NewButton("Append", func() {
    		content.Append(widget.NewLabel("Append"))
    	}))
    
    	w.SetContent(content)
    	w.Resize(fyne.NewSize(150, 150))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    盒子控件Box,其实就是一个容器类似于html中的div。不同的是在盒子创建时我们可选择widget.NewHBox()或widget.NewVBox()创建内部不同布局的盒子。在创建好Box盒子后,我们

    效果

    在这里插入图片描述

    Entry

    输入框(Entry)控件用于给用户输入简单的文本内容。我们可以调用widget.NewEntry()即可创建一个输入框控件。同时我们可以通过访问其Text字段来获得输入框中的内容。注册OnChange回调函数。每当内容有修改时,OnChange就会被调用。SetPlaceHolder()用来设置占位字符,设置字段MultilIne让输入框接受多行文本。此外,NewPasswordEntry()可创建一个密码输入框,输入的文本不会以明文显示。

    package main
    
    import (
    	"fmt"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Entry")
    
    	input := widget.NewEntry()
    	input.SetPlaceHolder("please enter name")
    	input.OnChanged = func(content string) {
    		fmt.Println("name", content)
    	}
    
    	passInput := widget.NewPasswordEntry()
    	passInput.SetPlaceHolder("please enter password")
    
    	line1 := widget.NewVBox(widget.NewLabel("Name"), layout.NewSpacer(), input)
    	line2 := widget.NewVBox(widget.NewLabel("Password"), layout.NewSpacer(), passInput)
    
    	loginBtn := widget.NewButton("Login", func() {
    		fmt.Printf("name: %s, password: %s\n Login in", input.Text, passInput.Text)
    	})
    
    	content := widget.NewVBox(line1, line2, loginBtn)
    	w.SetContent(content)
    	w.Resize(fyne.NewSize(150, 150))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    效果

    在这里插入图片描述

    Checkbox/Radio/Select

    这里的话主要是关于三种选择框的使用:

    • CheckBox 是简单的选择框
    • Radio 是单选框,只能选择其中的一个
    • Select是下拉框,当选项非常多时适合使用。
    package main
    
    import (
    	"fmt"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Entry")
    
    	input := widget.NewEntry()
    	input.SetPlaceHolder("please enter name")
    	input.OnChanged = func(content string) {
    		fmt.Println("name", content)
    	}
    
    	passInput := widget.NewPasswordEntry()
    	passInput.SetPlaceHolder("please enter password")
    
    	line1 := widget.NewVBox(widget.NewLabel("Name"), layout.NewSpacer(), input)
    	line2 := widget.NewVBox(widget.NewLabel("Password"), layout.NewSpacer(), passInput)
    
    	loginBtn := widget.NewButton("Login", func() {
    		fmt.Printf("name: %s, password: %s\n Login in", input.Text, passInput.Text)
    	})
    
    	sexRadio := widget.NewRadio([]string{"male", "female"}, func(value string) {
    		fmt.Printf("sex %s\n", value)
    	})
    	sexBox := widget.NewHBox(widget.NewLabel("Sex"), sexRadio)
    
    	provinceSelect := widget.NewSelect([]string{"beijing", "zhejiang", "shanghai"}, func(value string) {
    		fmt.Println("province:", value)
    	})
    	provinceBox := widget.NewHBox(widget.NewLabel("Province"), layout.NewSpacer(), provinceSelect)
    
    	content := widget.NewVBox(line1, line2, sexBox, provinceBox, loginBtn)
    	w.SetContent(content)
    	w.Resize(fyne.NewSize(150, 150))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    效果

    在这里插入图片描述

    Form

    表单控件Form用于对很多Label和输入控件进行布局。如果指定了OnSubmit或OnCancek函数,表单控件

    package main
    
    import (
    	"fmt"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Entry")
    	input := widget.NewEntry()
    	passWord := widget.NewPasswordEntry()
    	form := widget.NewForm(
    		&widget.FormItem{Text: "Name", Widget: input},
    		&widget.FormItem{Text: "password", Widget: passWord},
    	)
    	form.OnSubmit = func() {
    		fmt.Printf("Name: %s\nPassword: %s\n", input.Text, passWord.Text)
    	}
    	form.OnCancel = func() {
    		fmt.Printf("Login end")
    	}
    
    	w.SetContent(form)
    	w.Resize(fyne.NewSize(150, 150))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    效果

    在这里插入图片描述

    ProgressBar

    进度条(ProgressBar)用来表示任务的进度。例如文件下载的进度。创建当大widget.NewProgressBar(),默认最小值0.0,最大值为1.1,可通过Min/Max字段,调用SetValue()方法来控制进度,还有一种进度条是循环动画,表示任务在进行中。

    package main
    
    import (
    	"time"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Entry")
    	bar1 := widget.NewProgressBar()
    	bar1.Min = 0
    	bar1.Max = 100
    	bar2 := widget.NewProgressBarInfinite()
    	go func() {
    		for i := 0; i <= 100; i++ {
    			time.Sleep(time.Millisecond * 500)
    			bar1.SetValue(float64(i))
    		}
    	}()
    
    	content := widget.NewVBox(bar1, bar2)
    	w.SetContent(content)
    	w.Resize(fyne.NewSize(150, 150))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    效果

    在这里插入图片描述

    TabContainer

    标签容器(TabContainer)允许用户在不同的内容面板之间切换。标签可以是文本或图标。我们通过不同的方法创建不同位置的标签:

    • TabLocationBottom:显示在底部;
    • TabLocationLeading:显示在顶部左边;
    • TabLocationTrailing:显示在顶部右边。
    package main
    
    import (
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("TabContainer")
    	label1 := widget.NewLabel("label1")
    	label11 := widget.NewLabel("label11")
    	label11.Hide()
    	label2 := widget.NewLabel("label2")
    
    	showCheck := widget.NewCheck("Hidden?", func(val bool) {
    		if val {
    			label11.Hide()
    		} else {
    			label11.Show()
    		}
    	})
    	b1 := widget.NewHBox(
    		label1,
    		label11,
    		showCheck,
    	)
    	b2 := widget.NewHBox(
    		label2,
    	)
    	tabs := widget.NewTabContainer(
    		widget.NewTabItem("11", b1),
    		widget.NewTabItem("22", b2),
    	)
    
    	w.SetContent(tabs)
    	w.Resize(fyne.NewSize(150, 150))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    效果

    在这里插入图片描述

    Toolbar

    package main
    
    import (
    	"fmt"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/theme"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Toolbar")
    
    	toolbar := widget.NewToolbar(
    		widget.NewToolbarAction(theme.DocumentCreateIcon(), func() {
    			fmt.Println("create new Doc")
    		}),
    		widget.NewToolbarSeparator(),
    		widget.NewToolbarAction(theme.ContentCutIcon(), func() {
    			fmt.Println("Cut")
    		}),
    		widget.NewToolbarAction(theme.ContentCopyIcon(), func() {
    			fmt.Println("Copy")
    		}),
    		widget.NewToolbarAction(theme.ContentPasteIcon(), func() {
    			fmt.Println("Paste")
    		}),
    		widget.NewToolbarSpacer(),
    		widget.NewToolbarAction(theme.HelpIcon(), func() {
    			fmt.Println("Display help")
    		}),
    	)
    	content := fyne.NewContainerWithLayout(
    		layout.NewBorderLayout(toolbar, nil, nil, nil),
    		toolbar, widget.NewLabel("show Toolbar"),
    	)
    	w.SetContent(content)
    	w.Resize(fyne.NewSize(150, 150))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    效果

    在这里插入图片描述

    扩展

    下面我们通过扩展控件来让widget.Icon能够相应鼠标左键。

    package main
    
    import (
    	"fmt"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/theme"
    	"fyne.io/fyne/widget"
    )
    
    type tappableIcon struct {
    	widget.Icon
    }
    
    func newTappableIcon(res fyne.Resource) *tappableIcon {
    	icon := &tappableIcon{}
    	icon.ExtendBaseWidget(icon)
    	icon.SetResource(res)
    	return icon
    }
    
    type Tappable interface {
    	Tapped(*fyne.PointEvent)
    }
    
    // 鼠标左键单机事件
    func (t *tappableIcon) Tapped(e *fyne.PointEvent) {
    	// 输出鼠标相对于串口的绝对位置(窗口的左上角),相对位置(容器的左上角)
    	fmt.Println("tapped at", e)
    }
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Toolbar")
    	w.SetContent(newTappableIcon(theme.FyneLogo()))
    	w.Resize(fyne.NewSize(200, 200))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    效果

    在这里插入图片描述

    Layout

    布局(Layout)可以帮助我们在会使用控件的基础上,对控件的位置进行排版使之更加美观。

    BoxLayout

    package main
    
    import (
    	"image/color"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/canvas"
    	"fyne.io/fyne/layout"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Box Layout")
    
    	h1 := fyne.NewContainerWithLayout(
    		layout.NewHBoxLayout(),
    		canvas.NewText("left", color.Black),
    		layout.NewSpacer(),
    		canvas.NewText("right", color.Black),
    	)
    	h2 := fyne.NewContainerWithLayout(
    		layout.NewHBoxLayout(),
    		layout.NewSpacer(),
    		canvas.NewText("left", color.Black),
    		canvas.NewText("right", color.Black),
    	)
    	w.SetContent(fyne.NewContainerWithLayout(layout.NewVBoxLayout(), h1, h2))
    	w.Resize(fyne.NewSize(200, 200))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    效果

    在这里插入图片描述

    GridLayout

    网格布局,我们通过layout.NewGridLayout(cols),传入每行的列数来创建。使用该布局时,当我们缩放界面时控件的大小会自动调整

    package main
    
    import (
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/canvas"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/theme"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Grid Layout")
    	img1 := canvas.NewImageFromResource(theme.FyneLogo())
    	img2 := canvas.NewImageFromResource(theme.FyneLogo())
    	img3 := canvas.NewImageFromResource(theme.FyneLogo())
    	w.SetContent(fyne.NewContainerWithLayout(layout.NewGridLayout(2), img1, img2, img3))
    
    	w.Resize(fyne.NewSize(200, 200))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    效果
    在这里插入图片描述

    GridWrapLayout

    GridWrapLayout相当于时GridLayout的扩展版,我们可以在创建时指定每个子控件的size,当界面大小变化了这些子控件就会重新排列。

    package main
    
    import (
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/canvas"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/theme"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Grid Layout")
    	img1 := canvas.NewImageFromResource(theme.FyneLogo())
    	img2 := canvas.NewImageFromResource(theme.FyneLogo())
    	img3 := canvas.NewImageFromResource(theme.FyneLogo())
    	w.SetContent(fyne.NewContainerWithLayout(layout.NewGridWrapLayout(fyne.NewSize(100, 100)), img1, img2, img3))
    
    	w.Resize(fyne.NewSize(200, 200))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    效果

    在这里插入图片描述

    BorderLayout

    从名字我们大致可以才出来,这是一种边框布局。当我们需要把控件设置在四个方向的边框上时可以使用,最典型的就是Toolbar的布局。

    package main
    
    import (
    	"image/color"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/canvas"
    	"fyne.io/fyne/layout"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Grid Layout")
    	left := canvas.NewText("left", color.Black)
    	right := canvas.NewText("right", color.Black)
    	top := canvas.NewText("top", color.Black)
    	bottom := canvas.NewText("bottom", color.Black)
    	container := fyne.NewContainerWithLayout(
    		layout.NewBorderLayout(top, bottom, left, right),
    		top, bottom, left, right,
    	)
    	w.SetContent(container)
    	w.Resize(fyne.NewSize(200, 200))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    效果

    在这里插入图片描述

    FormLayout

    表单布局其实就是两列的GridLayout,但是做了一些微调。

    package main
    
    import (
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/widget"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Grid Layout")
    	input1 := widget.NewEntry()
    	input1.SetPlaceHolder("enter name")
    	input2 := widget.NewEntry()
    	input2.SetPlaceHolder("enter age")
    	label1 := widget.NewLabel("Name")
    	label2 := widget.NewLabel("age")
    	container := fyne.NewContainerWithLayout(
    		layout.NewFormLayout(),
    		label1, input1,
    		label2, input2,
    	)
    	w.SetContent(container)
    	w.Resize(fyne.NewSize(200, 200))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    效果

    在这里插入图片描述

    CenterLayout

    CenterLayout就是将空间布局在容器的中心位置,按照传入的顺序,后面传入的控件可能会遮挡前面传入的控件。

    package main
    
    import (
    	"image/color"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/canvas"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/theme"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Grid Layout")
    	image := canvas.NewImageFromResource(theme.FyneLogo())
    	// 设置图片为填充模式,会尽可能占满容器
        image.FillMode = canvas.ImageFillOriginal
    	text := canvas.NewText("Fyne Logo", color.Black)
    	container := fyne.NewContainerWithLayout(
    		layout.NewCenterLayout(),
    		image, text,
    	)
    	w.SetContent(container)
    	w.Resize(fyne.NewSize(200, 200))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    效果

    在这里插入图片描述

    MaxLayout

    MaxLayout会让容器中的元素都显示为最大的尺寸。

    package main
    
    import (
    	"image/color"
    
    	"fyne.io/fyne"
    	"fyne.io/fyne/app"
    	"fyne.io/fyne/canvas"
    	"fyne.io/fyne/layout"
    	"fyne.io/fyne/theme"
    )
    
    func test() {
    	a := app.New()
    	w := a.NewWindow("Max  Layout")
    	image := canvas.NewImageFromResource(theme.FyneLogo())
    	text := canvas.NewText("Fyne Logo", color.Black)
    	container := fyne.NewContainerWithLayout(
    		layout.NewMaxLayout(),
    		image, text,
    	)
    	w.SetContent(container)
    	w.Resize(fyne.NewSize(200, 200))
    	w.ShowAndRun()
    }
    
    func main() {
    	test()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    效果

    在这里插入图片描述

  • 相关阅读:
    【元宇宙欧米说】Black Cat 3D:CC0如何重构NFT生态系统
    结构型设计模式学习笔记
    SpringMVC之自定义注解
    【我不熟悉的javascript】JSON.stringify和JSON.parse方法详解
    【Python助力疫情管控】太方便啦~从100个不同格式的Excel文件里,1秒内找出1个人的详细信息
    TypeScript学习01--安装和基本数据类型
    springcloudalibaba架构(29): Seata分布式事务(AT模式)
    docker容器里面的java进程内存泄露排查
    java 获取15秒之前的时间
    带支付的客服系统2.0源码|多语言客服|Saas客服|多商户
  • 原文地址:https://blog.csdn.net/qq_52785898/article/details/126560402