go语言gui窗口应用之fyne框架-自定义容器实现自定义布局,更灵活的显示控件

news/2025/1/21 10:39:55/

一、自定义容器

在fyne中,所有的容器都是通过container包下的New函数定义的,先看源码:

go">package fyne// 根据布局创建容器
func New(layout fyne.Layout, objects ...fyne.CanvasObject) *fyne.Container {return &fyne.Container{Layout: layout, Objects: objects}
}

二、自定义布局

通过上述,可以看出,要实现自定义容器,关键是自定义布局,在 fyne 中,自定义布局,只要实现fyne包下Layout接口即可,以下为Layout接口源码:

go">package fyne// 布局接口
type Layout interface {// 通过遍历[]CanvasObject,获取每个控件,设置每个控件大小和位置Layout([]CanvasObject, Size)// 设置容器总大小(宽,高)MinSize(objects []CanvasObject) Size
}

三、我的自定义容器代码

  • 注意:自定义容器中控件宽、高,可能受自定义容器的外部容器影响,修改控件宽、高时,可能没有效果,需要对外部容器也要做相应操作。
  • 可以通过查看fynecontainer源码定义的布局,扩充自定义布局功能。

以下是我简易布局代码:

go">package mainimport ("fyne.io/fyne/v2""fyne.io/fyne/v2/container"
)// 自定义容器,按照控件实际大小,输入平均间隔距离
func NewMyBox(p float32, objects ...fyne.CanvasObject) *fyne.Container {return container.New(&myLayout{padding: p}, objects...)
}// 自定义布局
// 注意:自定义水平布局,最大高度受外部容器影响,可能不生效
type myLayout struct {padding float32 // 控件间隔
}// 设置每个控件大小和位置
func (l *myLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) {x := float32(0)                 // x坐标,控件距左边距离for _, child := range objects { // 循环遍历所有控件size = child.Size()                                      // 获取当前控件的设置的大小(宽、高)size.Height = child.Size().Height                        // 控件高度为控件的默认最小高度size.Width = fyne.Max(size.Width, child.MinSize().Width) // 控件的最小宽度和实际宽度取最大值child.Resize(size)                                       // 设置控件大小child.Move(fyne.NewPos(x, 0))                            // 设置控件位置x += size.Width + l.padding                              // 计算下一个控件位置}
}// 设置容器大小(宽,高)
func (l *myLayout) MinSize(objects []fyne.CanvasObject) fyne.Size {size := fyne.NewSize(0, 0)      // 初始化容器大小for _, child := range objects { // 循环遍历每个控件temp := fyne.NewSize(0, 0)                           // 临时存储获取的大小minSize := child.MinSize()                           // 控件最小绘制大小mSize := child.Size()                                // 控件设置大小temp.Height = fyne.Max(minSize.Height, mSize.Height) // 获取当前控件默认高度和设置高度的最大值size.Height = fyne.Max(size.Height, temp.Height)     // 设置容器最大高度为最高控件的高度值temp.Width = fyne.Max(minSize.Width, mSize.Width)    // 获取当前控件默认宽度和设置宽度的最大值size.Width += temp.Width + l.padding                 // 容器宽度 = 每个控件宽度 + 间距}return size // 返回容器大小
}

四、使用自定义容器

go">package mainimport ("fmt""fyne.io/fyne/v2"                //go get fyne.io/fyne/v2@latest"fyne.io/fyne/v2/app""fyne.io/fyne/v2/widget""github.com/flopp/go-findfont"  // go get github.com/flopp/go-findfont"os""strconv""strings"
)func init() {//设置中文字体:解决fyne中文乱码问题fontPaths := findfont.List()      // 获取系统中所有的字体路径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}}
}
func main() {myApp := app.New()                // 创建应用w := myApp.NewWindow("计数")      // 窗口标题w.Resize(fyne.NewSize(800, 400)) // 窗口大小w.CenterOnScreen()               // 窗口屏幕居中显示l1 := widget.NewLabel("设置计数:")     // 文本标签1l2 := widget.NewLabel("5")            // 文本标签2,默认为5b1 := widget.NewButton("+", func() {  // 按钮+v, _ := strconv.Atoi(l2.Text)     // 字符串转整型v++if v > 15 {                       // 最大值为15v = 15}l2.SetText(strconv.Itoa(v))      // 整型转字符串,赋值})b1.Resize(fyne.NewSize(b1.MinSize().Height, b1.MinSize().Height/3))  // 设置+按钮大小b2 := widget.NewButton("-", func() {v, _ := strconv.Atoi(l2.Text)    // 字符串转整型v--if v < 1 {                       // 最小值为1v = 1}l2.SetText(strconv.Itoa(v))      // 整型转字符串,赋值})b2.Resize(fyne.NewSize(b2.MinSize().Height, b2.MinSize().Height*5))  // 设置-按钮大小w.SetContent(NewMyBox(5, l1, l2, b1, b2))  // 使用自定义容器,控件间距设置为5w.ShowAndRun()                             // 显示窗口并运行应用
}

http://www.ppmy.cn/news/1564924.html

相关文章

Mysql--实战篇--mybatis cache(一级缓存,二级缓存,子查询主键主查询全部,查询条件加索引,覆盖索引等)

MyBatis是一个流行的Java持久层框架&#xff0c;它简化了JDBC的使用&#xff0c;允许开发者通过XML或注解的方式定义SQL语句&#xff0c;并将结果映射到Java对象。为了提高查询性能&#xff0c;MyBatis提供了缓存机制&#xff0c;可以在一定程度上减少数据库的访问次数&#xf…

Spring Boot中的配置文件有哪些类型

在 Spring Boot 中&#xff0c;配置文件用于管理应用程序的设置和参数&#xff0c;通常存放在项目的 src/main/resources 目录下。Spring Boot 支持多种类型的配置文件&#xff0c;并通过这些文件来控制应用的行为和环境配置。 1. application.properties application.proper…

数学基础 --线性代数之理解矩阵乘法

理解矩阵乘法的解析 矩阵乘法&#xff08;Matrix Multiplication&#xff09;是线性代数中的核心操作之一。在数学、几何和工程实际中&#xff0c;它不仅是一种代数运算规则&#xff0c;还承载着丰富的几何和映射意义。本文将从多个角度深入解析矩阵乘法&#xff0c;帮助读者理…

ros2-7.5 做一个自动巡检机器人

7.5.1 需求及设计 又到了小鱼老师带着做最佳实践项目了。需求&#xff1a;做一个在各个房间不断巡逻并记录图像的机器人。 到达目标点后首先通过语音播放到达目标点信息&#xff0c; 再通过摄像头拍摄一张图片保存到本地。 7.5.2 编写巡检控制节点 在chapt7_ws/src下新建功…

【解锁新技能!Flux.1如何实现远程AI生成图像随时随地创作】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

20250120面试鸭特训营第28天

更多特训营笔记详见个人主页【面试鸭特训营】专栏 250120 1. 说说 Java 中 HashMap 的原理&#xff1f; HashMap 的底层结构 HashMap 底层由 node 数组、单链表、红黑树构成。根据哈希函数计算得到哈希值&#xff0c;哈希值确定了元素保存在 node 数组中的具体下标。HashMap…

Ghost硬盘对拷教程分享

Ghost32是一款老古董级别的备份和恢复软件&#xff0c;通常用于创建系统镜像以及恢复系统。它最初由Symantec公司开发&#xff0c;用于在计算机系统上进行备份、克隆和恢复操作。 由于这个软件早已停止更新很多年了&#xff0c;并且也是全英文的用户界面&#xff0c;对国内用户…

山西省乡镇界面图层shp格式arcgis数据乡镇名称和编码2020年wgs84坐标无偏移测评

这篇文档将深入解析标题和描述中提及的IT知识点&#xff0c;主要关注地理信息系统&#xff08;GIS&#xff09;和ArcGIS软件的应用&#xff0c;以及shp文件格式的相关知识。 我们要理解"山西省乡镇界面图层shp格式arcgis数据乡镇名称和编码2020年wgs84坐标无偏移.zip&quo…