Fyne ( go跨平台GUI )中文文档-入门(一)
本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法go代码展示为Go 1.16 及更高版本, ide为goland2021.2
这是一个系列文章:Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客
Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客
Fyne ( go跨平台GUI )中文文档-绘图和动画(三)-CSDN博客
Fyne ( go跨平台GUI )中文文档-容器和布局 (四)-CSDN博客
Fyne ( go跨平台GUI )中文文档-小部件 (五)-CSDN博客
Fyne ( go跨平台GUI )中文文档- 数据绑定 (六)-CSDN博客
Fyne ( go跨平台GUI )中文文档- 扩展Fyne (七)-CSDN博客
Fyne ( go跨平台GUI )中文文档- 架构 (八)完结-CSDN博客
1.入门
1.1 介绍
基本环境
Fyne 需要存在 3 个基本元素,Go 工具(至少 1.12 版)、一个 C 编译器(用于连接系统图形驱动程序)和一个系统图形驱动程序。说明因您的操作系统而异,请选择下面的相应选项卡以获取安装说明。
请注意,这些步骤只是开发所必需的——您的 Fyne 应用程序不需要为最终用户进行任何设置或依赖安装!
window
- MSYS2 与 MingW-w64 - msys2.org
- Cygwin - cygwin.com
linux
- Debian / Ubuntu:
sudo apt-get install golang gcc libgl1-mesa-dev xorg-dev - Fedora:
sudo dnf install golang gcc libXcursor-devel libXrandr-devel mesa-libGL-devel libXi-devel libXinerama-devel libXxf86vm-devel
下载安装
使用 Go 模块(Go 1.16 及更高版本需要)时,您需要先设置模块,然后才能使用包。如果您没有使用模块或者您已经初始化了模块,则可以跳过此步骤进行下一步。
#创建项目
cd myapp
go mod init MODULE_NAME
#下载 Fyne
go get fyne.io/fyne/v2
下载运行fyne演示 ( fyne_demo )
go run fyne.io/fyne/v2/cmd/fyne_demo
1.2 hello world
一个简单的应用程序首先使用 app.New()创建一个应用程序实例,然后使用app.NewWindow()打开一个窗口。然后定义一个小部件树,在窗口上使用SetContent()将其设置为主要内容。然后通过在窗口上调用ShowAndRun()来显示应用程序 UI。
package mainimport ("fyne.io/fyne/v2/app""fyne.io/fyne/v2/widget"
)func main() {a := app.New()w := a.NewWindow("Hello World")w.SetContent(widget.NewLabel("Hello World!"))w.ShowAndRun()
}
使用go run .查看效果
默认深色风格, 如果您更喜欢浅色主题,则只需设置环境变量FYNE_THEME=light
1.3 应用和事件 (RunLoop)
为了使GUI应用程序正常工作,它需要运行一个事件(有时称为runloop)来处理用户交互和绘图事件。在 Fyne 中,这是使用App.Run() orWindow.ShowAndRun()函数开始的。必须从main()函数中设置代码的末尾调用其中之一。
一个应用程序应该只有一个运行循环,因此您应该只Run()在代码中调用一次。再次调用它会导致错误。
package mainimport ("fmt""fyne.io/fyne/v2/app""fyne.io/fyne/v2/widget"
)func main() {myApp := app.New()myWindow := myApp.NewWindow("Hello")myWindow.SetContent(widget.NewLabel("Hello"))myWindow.Show()myApp.Run()tidyUp()
}func tidyUp() {fmt.Println("Exited")
}
对于桌面运行时,可以通过调用直接退出App.Quit() 应用程序(移动应用程序不支持此功能) - 通常在开发人员代码中不需要。关闭所有窗口后,应用程序也将退出。另请参阅Run()在应用程序退出之前不会调用之后执行的函数。
1.4 更新内容
代码更新 GUI 的内容
//第一步是将要更新的小部件分配给变量。
clock := widget.NewLabel("")
w.SetContent(clock)
//将标签的内容设置为当前时间 Time.Format
formatted := time.Now().Format("Time: 03:04:05")
clock.SetText(formatted)
后台运行更新 GUI 的内容
大多数应用程序都需要在后台运行进程,例如下载数据或响应事件。为了模拟这一点,我们将扩展上面的代码以每秒运行一次。
与大多数 go 代码一样,我们可以创建一个 goroutine(使用go关键字)并在那里运行我们的代码。如果我们将文本更新代码移动到一个新函数中,它可以在初始显示以及定期更新的计时器上调用。通过结合 goroutine 和time.Tick内部的 for 循环,我们可以每秒更新标签。
go func() {for range time.Tick(time.Second) {updateTime(clock)}}()
将此代码放在ShowAndRun或Run调用之前很重要,因为它们在应用程序关闭之前不会返回。所有这些一起,代码将每秒运行并更新用户界面,创建一个基本的时钟小部件。完整代码如下:
package mainimport ("time""fyne.io/fyne/v2/app""fyne.io/fyne/v2/widget"
)func updateTime(clock *widget.Label) {formatted := time.Now().Format("Time: 03:04:05")clock.SetText(formatted)
}func main() {a := app.New()w := a.NewWindow("Clock")clock := widget.NewLabel("")updateTime(clock)w.SetContent(clock)go func() {for range time.Tick(time.Second) {updateTime(clock)}}()w.ShowAndRun()
}

1.5 窗口处理
窗口是使用该函数创建的,App.NewWindow()并且需要使用该Show()函数显示。辅助方法ShowAndRun()onfyne.Window允许您同时显示窗口和运行应用程序。
默认情况下,窗口的大小将通过检查MinSize()函数来显示其内容(在后面的示例中会详细介绍)。Window.Resize()您可以通过调用该方法来设置更大的尺寸。传入fyne.Size其中包含使用设备独立像素的宽度和高度,例如,默认情况下使窗口为正方形,我们可以:
w.Resize(fyne.NewSize(100, 100))
请注意,桌面环境可能具有导致窗口小于请求的限制。移动设备通常会忽略这一点,因为它们仅全屏显示。
如果您希望显示第二个窗口,您只能调用该Show() 函数。 如果您想在应用程序启动时打开多个窗口Window.Show(),拆分也很有帮助。App.Run()下面的示例显示了如何在启动时加载两个窗口。
package mainimport ("fyne.io/fyne/v2""fyne.io/fyne/v2/app""fyne.io/fyne/v2/widget"
)func main() {a := app.New()w := a.NewWindow("Hello World")w.SetContent(widget.NewLabel("Hello World!"))w.Show()w2 := a.NewWindow("Larger")w2.SetContent(widget.NewLabel("More content"))w2.Resize(fyne.NewSize(100, 100))w2.Show()a.Run()
}

当两个窗口都关闭时,上述应用程序将退出。如果您的应用程序被安排成一个窗口是主窗口而其他窗口是辅助视图,您可以将一个窗口设置为“主”窗口,以便在该窗口关闭时应用程序退出。为此,请使用 上的SetMaster()功能Window。
可以随时创建窗口,我们可以更改上面的代码,使第二个窗口 (w2) 的内容是一个打开新窗口的按钮。您还可以从更复杂的工作流程加载窗口,但要小心,因为新窗口通常会出现在当前活动内容之上。
w2.SetContent(widget.NewButton("Open new", func() {w3 := a.NewWindow("Third")w3.SetContent(widget.NewLabel("Third"))w3.Show()}))
1.6 单元测试
Fyne 的 API 旨在简化测试应用程序。通过将组件逻辑与其渲染定义分离,我们可以加载应用程序而无需实际显示它们并完全测试功能。
我们可以通过扩展我们的Hello World 应用程序来演示单元测试,以包含空间供用户输入他们的名字以迎接问候。我们首先更新用户界面,使其具有两个元素,一个Label用于问候语,一个Entry用于名称输入。container.NewVBox我们使用(一个垂直的盒子容器)显示它们,一个在另一个之上。更新后的用户界面代码如下所示:
func makeUI() (*widget.Label, *widget.Entry) {return widget.NewLabel("Hello world!"),widget.NewEntry()
}func main() {a := app.New()w := a.NewWindow("Hello Person")w.SetContent(container.NewVBox(makeUI()))w.ShowAndRun()
}
为了测试这个输入行为,我们创建了一个定义函数TestGreeter的新文件(名称结尾_test.go将其标记为测试) 。
package mainimport ("testing"
)func TestGreeting(t *testing.T) {
}
我们可以添加一个初始测试来验证初始状态,为此我们测试从 makeUI返回的 Label 的 Text字段和错误。 将以下代码添加到您的测试方法中:
out, in := makeUI()if out.Text != "Hello world!" {t.Error("Incorrect initial greeting")}
该测试将通过 - 接下来我们添加到测试中以验证欢迎程序。我们使用辅助测试场景的 Fynefyne.io/fyne/v2/test包,调用test.Type模拟用户输入。以下测试代码将检查输入用户名时输出是否更新(请务必添加导入):
test.Type(in, "Andy")if out.Text != "Hello Andy!" {t.Error("Incorrect user greeting")}
您可以使用 - 运行所有这些测试go test .,就像任何其他测试一样。这样做你现在会看到FAIL——因为我们没有添加欢迎逻辑。将函数更新makeUI为以下代码:
func makeUI() (*widget.Label, *widget.Entry) {out := widget.NewLabel("Hello world!")in := widget.NewEntry()in.OnChanged = func(content string) {out.SetText("Hello " + content + "!")}return out, in
}
这样做你会看到测试通过了。您还可以运行完整的应用程序(使用go run .)并在字段Entry中输入名称时查看问候语更新。另请注意,这些测试都在不显示窗口或窃取鼠标的情况下运行 - 这是Fyne单元测试设置的另一个好处。
1.7 打包
打包一个用于分发的图形应用程序可能很复杂。值得庆幸的是,“fyne”应用程序有一个“package”命令可以自动处理这个问题。只需指定目标操作系统和任何所需的元数据(例如图标)即可生成相应的包。.icns 或.ico 的图标转换将自动完成,因此只需提供一个.png文件 :)。
go install fyne.io/fyne/v2/cmd/fyne@latest
#macOS
fyne package -os darwin -icon myapp.png
#linux 和 Windows
fyne package -os linux -icon myapp.png
fyne package -os windows -icon myapp.png
1.8 移动端应用打包和分发
首先,您需要安装更多的开发工具来完成移动打包。adb对于 Android 构建,您必须安装 Android SDK 和 NDK 并设置适当的环境,以便可以在命令行上找到工具(例如)。要构建 iOS 应用程序,您需要在 macOS 计算机上安装 Xcode 以及命令行工具可选包。
fyne package -os android -appID com.example.myapp -icon mobileIcon.png
fyne package -os ios -appID com.example.myapp -icon mobileIcon.png
要在手机或模拟器上安装 android 应用程序,只需调用
adb install myapp.apk
要在iOS模拟器上安装,您可以使用如下命令行工具:
xcrun simctl install booted myapp.app
macOS 应用商店
先决条件:
- 运行 macOS 和 Xcode 的 Apple mac
- 苹果开发者账号
- Mac App Store 应用证书
- Mac App Store 安装程序证书
- App Store 中的 Apple Transporter 应用程序
-
设置您的应用程序/版本,以便在 AppStore Connect上上传构建。
-
打包完成的应用发布:
fyne release -appID com.example.myapp -appVersion 1.0 -appBuild 1 -category games -
将
.pkg拖到 Transporter 上,然后点击“交付”。 -
返回 AppStore Connect 网站,选择要发布的版本并提交审核。
谷歌商店(安卓)
先决条件:
- Google Play 管理中心帐户
- 分发密钥库( android 文档中的创建说明)
- 设置您的应用程序/版本,以便在 Google Play 控制台上上传。关闭“播放应用签名”选项,因为我们自己管理它。
- 打包完成的应用发布:
fyne release -os android -appID com.example.myapp -appVersion 1.0 -appBuild 1 - 将.apk文件拖入 Play 管理中心应用版本页面的构建放置区
- 开始推出新版本。
1.9 应用元数据
命令的v2.1.0 版本开始,fyne我们支持元数据文件,该文件允许您将有关您的应用程序的信息存储在存储库中。此文件是可选的,但有助于避免必须记住每个包和发布命令的特定构建参数。
该文件应该FyneApp.toml在您运行fyne命令的目录中命名(这通常是main包)。该文件的内容如下:
Website = "https://example.com"[Details]Icon = "app.png"Name = "测试元数据app"ID = "com.example.app"Version = "1.0.0"Build = 2
2.0 交叉编译
由于 Linux 系统能够轻松地交叉编译到 macOS 和 Windows,Fyne 开发人员推荐的工具是fyne-cross。它受到xgo的启发,并使用构建在golang-cross映像之上的docker映像,其中包括 Windows 的 MinGW 编译器和 macOS SDK,以及 Fyne 要求。
fyne-cross 允许为以下目标构建二进制文件并创建分发包:
| GOOS | GOARCH |
|---|---|
| darwin | amd64 |
| darwin | 386 |
| linux | amd64 |
| linux | 386 |
| linux | arm64 |
| linux | arm |
| windows | amd64 |
| windows | 386 |
| android | amd64 |
| android | 386 |
| android | arm64 |
| android | arm |
| ios | |
| freebsd | amd64 |
| freebsd | arm64 |
要求
- go >= 1.13
- docker
安装
go get github.com/fyne-io/fyne-cross
用法
fyne-cross <command> [options]The commands are:darwin Build and package a fyne application for the darwin OSlinux Build and package a fyne application for the linux OSwindows Build and package a fyne application for the windows OSandroid Build and package a fyne application for the android OSios Build and package a fyne application for the iOS OSfreebsd Build and package a fyne application for the freebsd OSversion Print the fyne-cross version informationUse "fyne-cross <command> -help" for more information about a command.
通配符
该arch标志支持通配符,以防要针对指定 GOOS 的所有支持的 GOARCH 进行编译
fyne-cross windows -arch=*
等同于
fyne-cross windows -arch=amd64,386
相关文章:
Fyne ( go跨平台GUI )中文文档-入门(一)
本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章: Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI )…...
Google 扩展 Chrome 安全和隐私功能
过去一周,谷歌一直在推出新特性和功能,旨在让用户在 Chrome 上的桌面体验更加安全,最新的举措是扩展在多个设备上保存密钥的功能。 到目前为止,Chrome 网络用户只能将密钥保存到 Android 上的 Google 密码管理器,然后…...
css 缩放会变动的需要使用转换
position: fixed;top: 170px;left: 50%;transform: translate(-50%, -50%);...
(17)数据库neo4j数据备份
图数据库备份 假设图数据库安装位置:/root/shuzihua/neo4j-community-3.5.8 1.数据导出 进入/root/shuzihua/neo4j-community-3.5.8/bin目录;执行 neo4j stop 停止服务;/root/shuzihua/neo4j-community-3.5.8/data/databases/graph.db&#…...
从零开始学习Python
目录 从零开始学习Python 引言 环境搭建 安装Python解释器 选择IDE 基础语法 注释 变量和数据类型 变量命名规则 数据类型 运算符 算术运算符 比较运算符 逻辑运算符 输入和输出 控制流 条件语句 循环语句 for循环 while循环 循环控制语句 函数和模块 定…...
前端框架的对比和选择
在当今的前端开发领域,有多种流行的前端框架可供选择,如 Vue、React 和 Angular。以下是这些框架的对比以及 Vue 的优势: 一、React 特点: 声明式编程:使用 JSX 语法,使得组件的结构和行为更加清晰。虚拟…...
《机器学习》周志华-CH7(贝叶斯分类)
7.1贝叶斯决策论 对分类任务而言,在所有相关概率已知的理想情形下,贝叶斯决策论考虑如何基于这些概率核误判损失来选择最优的类别标记。 R ( x i ∣ x ) ∑ j 1 N λ i j P ( c j ∣ x ) \begin{equation} R(x_{i}|x)\sum_{j1}^{N}\lambda_{ij}P(c_{j}…...
【C/C++】错题记录(一)
题目一 这道题主要考查了用户对标准库函数的使用规则的理解。 选项 A,一般情况下用户调用标准库函数前不需要重新定义,该项说法错误。 选项 B,即使包含了标准库头文件及相关命名空间,也不允许用户重新定义标准库函数,…...
【代码随想录训练营第42期 Day60打卡 - 图论Part10 - Bellman_ford算法系列运用
目录 一、Bellman_ford算法的应用 二、题目与题解 题目一:卡码网 94. 城市间货物运输 I 题目链接 题解:队列优化Bellman-Ford算法(SPFA) 题目二:卡码网 95. 城市间货物运输 II 题目链接 题解: 队列优…...
vue复制信息到粘贴框
npm install vue-clipboard2main.js文件引入 import VueClipboard from vue-clipboard2 Vue.use(VueClipboard)页面应用 copyInfo(info){let that thislet copyData 项目名称:${info.projectName}\n 用户名:${info.username}\n 初始密码:${…...
STM32基础笔记
第一章、STM32基本介绍 总内容 计算机技术简介环境安装、项目流程搭建最小系统时钟系统启动相关:启动文件、启动流程、启动方式GPIOUSARTNVIC: 外部中断_串口中断( DMA )TIMERADCDHT11: 单总线协议SPI : LCD屏 ## **1、计算机技术简介** 1.通用计算机/专用计算机…...
【深入学习Redis丨第六篇】Redis哨兵模式与操作详解
〇、前言 哨兵是一个分布式系统,你可以在一个架构中运行多个哨兵进程,这些进程使用流言协议来接收关于Master主服务器是否下线的信息,并使用投票协议来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。 文章目录 〇、…...
开源项目 GAN 漫画风格化 UGATIT
开源项目:DataBall / UGATIT GitCode * 数据集 * [该项目制作的训练集的数据集下载地址(百度网盘 Password: gxl1 )](https://pan.baidu.com/s/1683TRcv3r3o7jSitq3VyYA) * 预训练模型 * [预训练模型下载地址(百度网盘 Password: khbg )](https://pan.ba…...
SegFormer网络结构的学习和重构
因为太多的博客并没有深入理解,本文是自己学习后加入自己深入理解的总结记录,方便自己以后查看。 segformer中encoder、decoder的详解。 学习前言 一起来学习Segformer的原理,如果有用的话,请记得点赞关注哦。 一、Segformer的网络结构图 网络结构&…...
ubuntu个人实用配置问题
记录两年前试图用Ubuntu作为自己的日常系统的实际情况 记录时间2022年8月26日 中间连输入法都安装不上。。哈哈又被自己笑到啦! ubuntu 安装 使用市面上的各种 U 盘启动盘制作工具,下载 iso 文件之后将清空指定的 U 盘并制作为启动 U 盘,…...
Xk8s证书续期
Master节点 备份文件 cp -r /etc/kubernetes/ /etc/kubernetes-20211021-bak tar -cvzf kubernetes-20211021-bak.tar.gz /etc/kubernetes-20211021-bak/cp -r ~/.kube/ ~/.kube-20211021-bak tar -cvzf kube-20211021-bak.tar.gz ~/.kube-20211021-bakcp -r /var/lib/kube…...
仓颉编程入门2,启动HTTP服务
上一篇配置了仓颉sdk编译和运行环境,读取一个配置文件,并把配置文件简单解析了一下。 前面读取配置文件,使用File.readFrom(),这个直接把文件全部读取出来,返回一个字节数组。然后又创建一个字节流,给文件…...
Linux驱动开发初识
Linux驱动开发初识 文章目录 Linux驱动开发初识一、驱动的概念1.1 什么是驱动:1.2 驱动的分类: 二、设备的概念2.1 主设备号&次设备号:2.2 设备号的作用: 三、设备驱动整体调用过程3.1 上层用户操控设备的流程:3.2…...
前端面试题(三)
11. Web API 面试题 如何使用 fetch 发起网络请求? fetch 是现代浏览器中用于发起网络请求的原生 API。它返回一个 Promise,默认情况下使用 GET 请求:fetch(https://api.example.com/data).then(response > response.json()).then(data &g…...
骨传导耳机哪个牌子最好用?实测五大实用型骨传导耳机分析!
在快节奏的现代生活中,耳机已成为我们不可或缺的伴侣。无论是在通勤路上、运动时,还是在安静的图书馆,耳机都能为我们提供一片属于自己的音乐天地。然而,长时间使用传统耳机可能会对听力造成损害,尤其是在高音量下。因…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

