自学内容网 自学内容网

go语言gui窗口应用之fyne框架-动态添加、删除一行控件(逐行注释)

演示动画

在这里插入图片描述

功能

  • 动态添加一行控件
  • 最多添加5行
  • 可添加文件夹路径
  • 动态删除本行控件

全部代码

package main

import (
"fmt"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/widget"
"github.com/flopp/go-findfont"
"os"
"strconv"
"strings"
)

func init() {
//设置中文字体:解决中文乱码问题
fontPaths := findfont.List()     // win系统中所有字体路径
for _, path := range fontPaths { // 循环遍历所有路径,选择设置的字体
if strings.Contains(path, "msyh.ttf") || strings.Contains(path, "simhei.ttf") || strings.Contains(path, "simsun.ttc") || strings.Contains(path, "simkai.ttf") || strings.Contains(path, "STHeiti Medium.ttc") || strings.Contains(path, "Songti.ttc") {
os.Setenv("FYNE_FONT", path) // 第一个系统存在的字体,设置为本应用字体
break
}
}
}

type MyWidget struct {            // 存储一行添加的控件
id        int                 // 本行控件的id,方便删除
myWidgets []fyne.CanvasObject // 本行控件
}

var (
l11, l12, l41 *widget.Label  // 固定显示的标签,非动态添加的标签
b31           *widget.Button // 固定显示的按钮,非动态添加的按钮
sid           int            // 存储id自增值,用于区别动态添加的一行控件的唯一性
)
var myWidgetList []*MyWidget // 存储所有动态添加的控件行
var cc = &fyne.Container{}   // 用于存储每行布局(或控件),方便更新整个竖向布局
func main() {
myApp := app.NewWithID("com.xiantianshizhong.gogyne")    // 创建应用,设置唯一id
w := myApp.NewWindow("竖向中间位置动态添加一行控件")        // 新建窗口,设置窗口标题
w.Resize(fyne.NewSize(800, 400))                        // 设置窗口大小
w.CenterOnScreen()                                      // 窗口居中显示

// ——————动态添加控件前面的控件,本实例为第一行——————
l11 = widget.NewLabel("添加控件行数:")
l12 = widget.NewLabel("0")

// ——————动态添加控件后面的控件,本实例为添加控件按钮——————
b31 = widget.NewButton("添加控件", func() {
addContainer(w) // 添加控件方法
})

// ——————后面的控件,本实例为标签描述——————
l41 = widget.NewLabel("其他控件...")

// ——————刷新布局——————
refreshlayout(w)

// ——————显示窗口并运行应用——————
w.ShowAndRun()
}

// 动态添加控件方法
func addContainer(w fyne.Window) { // 动态添加
n := len(myWidgetList) // 当前动态添加的控件数量
if n < 5 {             // 最多添加5行
ll1 := widget.NewLabel("")                // 本行序号,刷新布局时重新设置
ee := widget.NewEntry()                   // 文本框,本应用占位用,无意义
ll2 := widget.NewLabel("请点击右边按钮选择文件夹...") // 标签,用于显示选择的文件夹路径
bb1 := widget.NewButton("选择文件夹", func() { // 选择文件夹路径按钮
dialog.NewFolderOpen(func(uri fyne.ListableURI, err error) { // 文件夹选择对话框
if uri != nil { // 取消选择时为nil,不判断会报错退出应用
ll2.SetText(uri.Path()) // 将选择的文件夹路径赋值给标签显示
}
}, w).Show() // 展示对话框
})
var bb2 *widget.Button // 删除本行动态添加的控件按钮
bb2 = widget.NewButton("删除本行", func() {
var ctemp []*MyWidget            // 临时存放不删除的动态控件行
for _, c := range myWidgetList { // 循环遍历所有动态添加的控件行
b, _ := c.myWidgets[4].(*widget.Button) // 获取每行的删除按钮
if bb2 == b {                           // 存储的删除按钮,与本按钮内存地址相同,为统一按钮
fmt.Println(c.id)
continue // 不存储本行控件,不存储就等于删除
}
ctemp = append(ctemp, c) // 将不删除的控件行,添加到临时控件列表
}
myWidgetList = ctemp // 将删除掉的控件列表,重新赋值给动态控件列表
refreshlayout(w)     // 刷新布局后,就不存在当前控件行
})
sid++                                                       // 当前行的id值
myw := new(MyWidget)                                        // 存储新的一行控件
myw.id = sid                                                // 新的一行控件的唯一id
myw.myWidgets = []fyne.CanvasObject{ll1, ee, ll2, bb1, bb2} // 新的一行控件
myWidgetList = append(myWidgetList, myw)                    // 将一行动态控件加到数组,ctemp存储所有动态添加的控件
// 添加一行后,必须刷新布局,就多了一行控件
refreshlayout(w)
}
}

// 每次变动都要,刷新窗口布局
func refreshlayout(w fyne.Window) {
n := len(myWidgetList)                                       // 动态添加控件的行数
l12.SetText(strconv.Itoa(n))                                 // 设置显示动态控件行数
cc = &fyne.Container{}                                       // 重新布置所有布局的总容器
cc.Objects = append(cc.Objects, container.NewHBox(l11, l12)) // 添加第一行布局到总容器
for i, c := range myWidgetList {                             // 循环添加动态添加的每行控件
v, _ := c.myWidgets[0].(*widget.Label)                               // 获取每行的序号标签
v.SetText(strconv.Itoa(i + 1))                                       // 按照顺序设置序号标签,添加、删除后,序号都重新排序
cc.Objects = append(cc.Objects, container.NewHBox((c.myWidgets)...)) // 将本行控件放在横向容器中,并添加到总容器
}
cc.Objects = append(cc.Objects, b31, l41)      // 添加动态控件后的控件
w.SetContent(container.NewVBox(cc.Objects...)) // 将容器中每行容器或控件展开,用于垂直布局到行
}

原文地址:https://blog.csdn.net/qq_30712797/article/details/145302695

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!