Fyne 是一个使用 Go 编写的易于使用的 UI 工具包和应用程序 API。 它旨在构建使用单一代码库在桌面和移动设备上运行的应用程序。 2.3 版是 Fyne API 的当前版本,它添加了改进的主题设计、云存储、改进的国际语言文本处理和许多较小的功能添加。
github地址:https://github.com/fyne-io/fyne
要使用Fyne开发应用,你需要Go 1.14或更高版本,C编译器和系统开发工具。如果您不确定是否全部安装了,或者不知道如何安装,参考官方文档:https://developer.fyne.io/started/#prerequisites
使用标准的go工具,安装Fyne的核心库使用:
go get fyne.io/fyne/v2@latest
go install fyne.io/fyne/v2/cmd/fyne@latest
在编写应用程序代码或运行示例之前,您可以使用 Fyne 安装工具检查您的安装。只需从链接下载适合您计算机的应用程序并运行它,您应该会看到类似以下屏幕的内容:
如果您的安装有任何问题,请参阅故障排除部分以获取提示。
请注意,第一次运行必须编译一些 C 代码,因此可能需要比平时更长的时间。后续构建会重用缓存,速度会快很多。
go run fyne.io/fyne/v2/cmd/fyne_demo@latest
运行会自动下载相应的依赖:
运行结果, 看起来还不错:
更多详情可访问官方文档:https://developer.fyne.io/started/#run-the-demo
创建你的第一个Hello world程序:
main.go
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/widget"
)
func main() {
app := app.New() // 创建应用程序实例
window := app.NewWindow("Hello world") // 创建窗口,标题为"Hello Wolrd"
window.SetContent(widget.NewLabel("Hello world!")) // 往窗口中放入一个内容为"Hello world!"的标签控件
window.ShowAndRun() //展示并运行程序
}
一个简单的应用程序首先使用 app.New()
创建一个应用程序实例,然后使用 app.NewWindow()
打开一个窗口。然后定义了一个小部件树,它被设置为窗口上的 SetContent()
的主要内容。然后通过在窗口上调用 ShowAndRun()
来显示应用程序 UI。
上面的代码可以使用命令构建go build .
,然后通过运行hello
命令或双击图标来执行。您也可以绕过编译步骤,直接使用go run .
.
两种方法都会显示一个如下所示的窗口:
如果您更喜欢浅色主题,则只需设置环境变量FYNE_THEME=light
即可:
要使 GUI 应用程序正常工作,它需要运行一个事件循环(有时称为运行循环)来处理用户交互和绘图事件。在 Fyne 中,这是使用App.Run()
或Window.ShowAndRun()
函数开始的。其中之一必须从函数中设置代码的末尾调用main()
。
一个应用程序应该只有一个运行循环,因此您应该只Run()
在代码中调用一次。第二次调用它会导致错误。
package main
import (
"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("运行成功") //程序退出后才会执行
}
对于桌面运行时,可以通过调用直接退出应用程序App.Quit()
(移动应用程序不支持此功能)——通常在开发人员代码中不需要。一旦所有窗口关闭,应用程序也将退出。Run()
另请参阅在应用程序退出之前不会调用之后执行的函数。
实现一个简单的时钟,在界面上显示时间。
第一步是将要更新的小部件分配给一个变量。widget.NewLabel
在我们直接传入的hello world 教程中SetContent()
,为了更新它,我们将其更改为两行不同的代码,例如:
clock := widget.NewLabel("")
w.SetContent(clock)
一旦将内容分配给变量,我们就可以调用函数,例如SetText("new text")
. 对于我们的示例,我们将在 的帮助下将标签的内容设置为当前时间 Time.Format
。
formatted := time.Now().Format("Time: 03:04:05")
clock.SetText(formatted)
这就是我们更改可见项目的内容所需要做的一切(完整代码见下文)。但是,我们可以更进一步,定期更新内容。
大多数应用程序都需要有在后台运行的进程,例如下载数据或响应事件。为了模拟这一点,我们将扩展上面的代码以每秒运行一次。
与大多数 go 代码一样,我们可以创建一个 goroutine(使用关键字go
)并在那里运行我们的代码。如果我们将文本更新代码移动到一个新函数中,它可以在初始显示时调用,也可以在计时器上调用以进行定期更新。通过结合一个 goroutine 和 time.Tick
内部的 for 循环,我们可以每秒更新一次标签。
package main
import (
"time"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/widget"
)
func main() {
app := app.New() // 创建应用程序实例
window := app.NewWindow("Hello world") // 创建窗口,标题为"Hello Wolrd"
clock := widget.NewLabel("")
updateTime(clock)
go func() {
for range time.Tick(time.Second) {
updateTime(clock) // 每秒更新一次时间
}
}()
window.SetContent(clock) // 往窗口中放入一个内容为"Hello world!"的标签控件
window.ShowAndRun() //展示并运行程序
}
func updateTime(clock *widget.Label) {
formatted := time.Now().Format("Time: 03:04:05") //获取格式化时间
clock.SetText(formatted)
}
效果如下:
窗口是使用该函数创建的App.NewWindow()
,需要使用该Show()
函数来显示。辅助方法ShowAndRun()
onfyne.Window
允许您在显示窗口的同时运行应用程序。
默认情况下,窗口的大小将是正确的,以通过检查函数来显示其内容MinSize()
(在后面的示例中会详细介绍)。您可以通过调用该方法设置更大的尺寸Window.Resize()
。向其中传递一个 a fyne.Size
,其中包含使用设备独立像素的宽度和高度(意味着它在不同设备上将是相同的),例如默认情况下使窗口为正方形我们可以:
w.Resize(fyne.NewSize(100, 100))
请注意,桌面环境可能具有导致窗口小于请求的限制。移动设备通常会忽略这一点,因为它们仅以全屏显示。
如果你想显示第二个窗口,你必须只调用该Show()
函数。 如果您想在应用程序启动时打开多个窗口,那么Window.Show()
拆分也很有用。App.Run()
下面的示例显示了如何在启动时加载两个窗口。
package main
import (
"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()
on 上的功能Window
。
窗口可以随时创建,我们可以更改上面的代码,让第二个窗口(w2
)的内容是一个打开新窗口的按钮。您还可以从更复杂的工作流程加载窗口,但要小心,因为新窗口通常会出现在当前活动内容的上方。
w2.SetContent(widget.NewButton("Open new", func() {
w3 := a.NewWindow("Third")
w3.SetContent(widget.NewLabel("Third"))
w3.Show()
}))
完成代码如下:
package main
import (
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/widget"
)
func main() {
app := app.New() // 创建应用程序实例
window := app.NewWindow("Hello world") // 创建窗口,标题为"Hello Wolrd"
clock := widget.NewLabel("")
updateTime(clock)
go func() {
for range time.Tick(time.Second) {
updateTime(clock) // 每秒更新一次时间
}
}()
window.SetContent(clock) // 往窗口中放入一个内容为"Hello world!"的标签控件
window.Show() //展示窗口1
window2 := app.NewWindow("Larger Window")
window2.SetContent(widget.NewButton("Open New", func() {
window3 := app.NewWindow("Third")
window3.SetContent(widget.NewLabel("Third"))
window3.Show()
}))
window2.Resize(fyne.NewSize(100, 100)) // 设置窗口大小
window2.Show()
app.Run()
}
func updateTime(clock *widget.Label) {
formatted := time.Now().Format("Time: 03:04:05") //获取格式化时间
clock.SetText(formatted)
}
打包用于分发的图形应用程序可能很复杂。图形应用程序通常具有与之相关的图标和元数据,以及与每个环境集成所需的特定格式。Windows 可执行文件需要嵌入图标,macOS 应用程序是捆绑包,对于 Linux,应该安装各种元数据文件。好麻烦!
值得庆幸的是,“fyne”应用程序有一个“package”命令可以自动处理这个问题。只需指定目标操作系统和任何所需的元数据(例如图标)即可生成适当的包。.icns
或 .ico
的图标转换将自动完成,因此只需提供一个 .png
文件 。您所需要的只是已经为目标平台构建了应用程序…
go install fyne.io/fyne/v2/cmd/fyne@latest
fyne package -os darwin -icon myapp.png
如果你使用的是旧版本的 Go (<1.16),你应该使用安装 fynego get
go get fyne.io/fyne/v2/cmd/fyne
fyne package -os darwin -icon myapp.png
将创建 myapp.app,这是一个完整的捆绑结构,用于分发给 macOS 用户。然后你也可以构建 linux 和 Windows 版本……
fyne package -os linux -icon myapp.png
fyne package -os windows -icon myapp.png
这些命令将创建:
如果您只想在您的计算机上安装桌面应用程序,那么您可以使用有用的安装子命令。例如,要在整个系统范围内安装您当前的应用程序,您可以简单地执行以下命令:
fyne install -icon myapp.png
所有这些命令还支持一个默认的图标文件,Icon.png
这样您就可以避免为每次执行键入参数。从 Fyne 2.1 开始,还有一个 元数据文件,您可以在其中为项目设置默认选项。
当然,如果您愿意,您仍然可以使用标准的 Go 工具运行您的应用程序。
自发布 v2.1.0 命令以来,fyne
支持元数据文件,该文件允许您将有关应用程序的信息存储在存储库中。此文件是可选的,但可以帮助避免必须记住每个包和发布命令的特定构建参数。
FyneApp.toml
该文件应在您运行命令的目录中命名fyne
(这通常是main
包)。文件内容如下:
Website = "https://example.com"
[Details]
Icon = "Icon.png"
Name = "My App"
ID = "com.example.app"
Version = "1.0.0"
Build = 1
文件的顶部是元数据,如果您将应用程序上传到 https://apps.fyne.io 列表页面,将使用该元数据,因此它是可选的。[详细信息] 部分包含有关您的应用程序的数据,这些数据会在其他应用程序商店和操作系统的发布过程中使用。如果找到该文件,fyne 工具将使用该文件,如果存在元数据,则不需要许多强制命令参数。您仍然可以使用命令行参数覆盖这些值。
GOOS
使用 Go 进行交叉编译的目的很简单——我们只需为目标操作系统设置环境变量(GOARCH
如果目标是不同的体系结构)。不幸的是,当使用原生图形调用时,在 Fyne 中使用 CGo 会使这变得有点困难。
要交叉编译 Fyne 应用程序,您还必须设置CGO_ENABLED=1
which tells go 以启用 C 编译器(当目标平台与当前系统不同时,这通常会关闭)。不幸的是,这样做意味着您必须有一个适用于您要编译的目标平台的 C 编译器。安装合适的编译器后,您还需要设置CC
环境变量来告诉 Go 使用哪个编译器。
有许多方法可以安装所需的工具——以及可以使用的不同工具。Fyne 开发者推荐的配置是:
GOOS(目标) | CC | 供应商 | 下载 | 笔记 |
---|---|---|---|---|
darwin |
o32-clang |
osxcross | 来自 github.com | 您还需要安装 macOS SDK(下载链接中的说明) |
windows |
x86_64-w64-mingw64-gcc |
mingw64 | 包管理器 | 对于 macOS 使用自制软件 |
linux |
gcc 或者x86_64-linux-musl-gcc |
gcc 或 musl-cross | cygwin或包管理器 | musl-cross 可从homebrew获得以提供 linux gcc。您还需要安装 X11 和 mesa 头文件进行编译。 |
使用上面设置的环境变量,您应该能够以通常的方式进行编译。如果出现更多错误,很可能是由于缺少包。一些目标平台需要安装额外的库或头文件才能成功编译。
由于 Linux 系统能够轻松交叉编译到 macOS 和 Windows,因此当您不是从 Linux 开发时,使用虚拟化环境会更简单。Docker 镜像是用于复杂构建配置的有用工具,这也适用于 Fyne。可以使用不同的工具。Fyne 开发者推荐的工具是fyne-cross。它受到xgo的启发,并使用构建在golang-cross图像之上的docker 图像,其中包括适用于 windows 的 MinGW 编译器和 macOS SDK,以及 Fyne 要求。
fyne-cross 允许为以下目标构建二进制文件和创建分发包:
谷歌 | GOARCH |
---|---|
达尔文 | amd64 |
达尔文 | 386 |
Linux | amd64 |
Linux | 386 |
Linux | arm64 |
Linux | 手臂 |
视窗 | amd64 |
视窗 | 386 |
安卓 | amd64 |
安卓 | 386 |
安卓 | arm64 |
安卓 | 手臂 |
ios | |
自由系统 | amd64 |
自由系统 | arm64 |
注意:仅在 darwin 主机上支持 iOS 编译。
您可以fyne-cross
使用以下命令进行安装(需要 Go 1.16 或更高版本):
go install github.com/fyne-io/fyne-cross@latest
对于早期版本的 Go,您需要改用以下命令:
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 OS
linux Build and package a fyne application for the linux OS
windows Build and package a fyne application for the windows OS
android Build and package a fyne application for the android OS
ios Build and package a fyne application for the iOS OS
freebsd Build and package a fyne application for the freebsd OS
version Print the fyne-cross version information
Use "fyne-cross -help" for more information about a command.
该arch
标志支持通配符,以防针对指定 GOOS 的所有支持的 GOARCH 进行编译
例子:
fyne-cross windows -arch=*
相当于
fyne-cross windows -arch=amd64,386
下面的示例交叉编译和打包fyne 示例应用程序
git clone https://github.com/fyne-io/examples.git
cd examples
fyne-cross linux
注意:默认情况下,fyne-cross 会将包编译到当前目录。
上面的命令等同于:
fyne-cross linux .
fyne-cross linux -output bugs ./cmd/bugs
在 Fyne 中,aCanvas
是绘制应用程序的区域。每个窗口都有一个可以访问的画布Window.Canvas()
,但通常您会在其中找到Window
避免访问画布的功能。
可以在 Fyne 中绘制的所有内容都是CanvasObject
. 这里的示例打开一个新窗口,然后通过设置窗口画布的内容来显示不同类型的图元图形元素。如文本和圆圈示例所示,可以通过多种方式自定义每种类型的对象。
除了更改显示的内容外,Canvas.SetContent()
还可以更改当前可见的内容。例如,如果您更改FillColour
矩形的 ,您可以使用 请求刷新此现有组件rect.Refresh()
。
package main
import (
"image/color"
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
)
func main() {
myApp := app.New()
myWindow := myApp.NewWindow("Canvas")
myCanvas := myWindow.Canvas()
blue := color.NRGBA{R: 0, G: 0, B: 180, A: 255}
rect := canvas.NewRectangle(blue)
myCanvas.SetContent(rect)
go func() {
time.Sleep(time.Second)
green := color.NRGBA{R: 0, G: 180, B: 0, A: 255}
rect.FillColor = green
rect.Refresh()
}()
myWindow.Resize(fyne.NewSize(100, 100))
myWindow.ShowAndRun()
}
我们可以用同样的方式画出很多不同的绘图元素,比如圆形、文字。
func setContentToText(c fyne.Canvas) {
green := color.NRGBA{R: 0, G: 180, B: 0, A: 255}
text := canvas.NewText("Text", green)
text.TextStyle.Bold = true
c.SetContent(text)
}
func setContentToCircle(c fyne.Canvas) {
red := color.NRGBA{R: 0xff, G: 0x33, B: 0x33, A: 0xff}
circle := canvas.NewCircle(color.White)
circle.StrokeWidth = 4
circle.StrokeColor = red
c.SetContent(circle)
}
Afyne.Widget
是一种特殊类型的画布对象,它具有与之关联的交互元素。在小部件中,逻辑与其看起来的方式(也称为WidgetRenderer
)是分开的。
小部件也是类型CanvasObject
,因此我们可以将窗口的内容设置为单个小部件。看看我们如何在这个例子中新建一个 widget.Entry
并将其设置为窗口的内容。
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/widget"
)
func main() {
myApp := app.New()
myWindow := myApp.NewWindow("Widget")
myWindow.SetContent(widget.NewEntry())
myWindow.ShowAndRun()
}
在前面的示例中,我们看到了如何将 a 设置CanvasObject
为 a 的内容Canvas
,但是仅显示一个可视元素并不是很有用。要显示多个项目,我们使用Container
type。
由于 thefyne.Container
也是 a fyne.CanvasObject
,我们可以将它设置为 a 的内容fyne.Canvas
。在此示例中,我们创建了 3 个文本对象,然后使用函数将它们放置在容器中container.NewWithoutLayout()
。由于没有布局集,我们可以像您看到的那样移动元素text2.Move()
。
package main
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
//"fyne.io/fyne/v2/layout"
)
func main() {
myApp := app.New()
myWindow := myApp.NewWindow("Container")
green := color.NRGBA{R: 0, G: 180, B: 0, A: 255}
text1 := canvas.NewText("Hello", green)
text2 := canvas.NewText("There", green)
text2.Move(fyne.NewPos(20, 20))
// content := container.NewWithoutLayout(text1, text2)
content := container.New(layout.NewGridLayout(2), text1, text2)
myWindow.SetContent(content)
myWindow.ShowAndRun()
}
Afyne.Layout
实现了一种在容器中组织项目的方法。通过取消注释container.New()
此示例中的行,您可以更改容器以使用具有 2 列的网格布局。运行此代码并尝试调整窗口大小以查看布局如何自动配置窗口的内容。text2
另请注意,布局代码会忽略的手动位置。
自 v2.2.0 发布以来,Fyne 内置了对系统托盘菜单的支持。此功能在 macOS、Windows 和 Linux 计算机上显示一个图标,点击时将弹出应用程序指定的菜单。
由于这是一项特定于桌面的功能,我们必须首先进行运行时检查以确保应用程序在桌面模式下运行。为此,并获得对桌面功能的引用,我们执行 Go 类型断言:
if desk, ok := a.(desktop.App); ok {
...
}
如果ok
变量为真,那么我们可以使用您之前可能使用过的标准 Fyne 菜单 API 设置菜单Window.SetMainMenu
。
m := fyne.NewMenu("MyApp",
fyne.NewMenuItem("Show", func() {
log.Println("Tapped show")
}))
desk.SetSystemTrayMenu(m)
将此代码添加到应用程序的设置中后,您可以运行该应用程序并看到它在系统托盘中显示了一个 Fyne 图标。当您点击它时,将出现一个包含“显示”和“退出”的菜单。
默认图标是 Fyne 徽标,您可以使用应用程序元数据 或直接使用 将应用程序图标设置App.SetIcon
为系统托盘来修复此问题desk.SetSystemTrayIcon
。
默认情况下,当您关闭所有窗口时,Fyne 应用程序将退出,这可能不是您想要的系统托盘应用程序。要覆盖行为,您可以使用该Window.SetCloseIntercept
功能来覆盖关闭窗口时发生的情况。在下面的示例中,我们隐藏窗口而不是通过调用 Window.Hide()
. 在第一次显示窗口之前添加它。
w.SetCloseIntercept(func() {
w.Hide()
})
隐藏窗口的好处是您可以简单地再次显示它, Window.Show()
如果第二次需要相同的内容,这比创建一个新窗口更有效。我们更新之前创建的菜单以显示上面隐藏的窗口。
fyne.NewMenuItem("Show", func() {
w.Show()
}))
package main
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/widget"
)
func main() {
a := app.New()
w := a.NewWindow("SysTray")
if desk, ok := a.(desktop.App); ok {
m := fyne.NewMenu("MyApp",
fyne.NewMenuItem("Show", func() {
w.Show()
}))
desk.SetSystemTrayMenu(m)
}
w.SetContent(widget.NewLabel("Fyne System Tray"))
w.SetCloseIntercept(func() {
w.Hide()
})
w.ShowAndRun()
}
canvas.Rectangle
是 Fyne 中最简单的画布对象。它显示指定颜色的块。您还可以使用字段设置颜色FillColor
。
在此示例中,矩形填充窗口,因为它是唯一的内容元素。
package main
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
)
func main() {
myApp := app.New()
w := myApp.NewWindow("Rectangle")
color := color.NRGBA{R: 255, G: 0, B: 180, A: 255}
rect := canvas.NewRectangle(color)
w.SetContent(rect)
w.Resize(fyne.NewSize(150, 100))
w.ShowAndRun()
}
canvas.Text
用于 Fyne 内的所有文本渲染。它是通过指定文本的文本和颜色来创建的。使用当前主题指定的默认字体呈现文本。
文本对象允许某些配置,如Alignment
和TextStyle
字段。如此处的示例所示。要改用等宽字体,您可以指定 fyne.TextStyle{Monospace: true}
.
package main
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
)
func main() {
myApp := app.New()
w := myApp.NewWindow("Rectangle")
color := color.NRGBA{R: 255, G: 0, B: 180, A: 255}
// 设置文本
text := canvas.NewText("Text Object", color)
text.Alignment = fyne.TextAlignTrailing
text.TextStyle = fyne.TextStyle{Italic: true}
w.SetContent(text)
w.Resize(fyne.NewSize(150, 100))
w.ShowAndRun()
}
可以通过指定FYNE_FONT
环境变量来使用替代字体。使用它来设置.ttf
要使用的文件,而不是 Fyne 工具包或当前主题中提供的文件。
该对象从(默认为顶部,左侧)到(默认为底部,右侧)canvas.Line
画一条线。您可以指定其颜色并可以改变笔划宽度,否则默认为.Position1``Position2``1
Position1
可以使用或Position2
字段或使用Move()
和函数来操作行位置Resize()
。例如,宽度为 0 的区域将显示垂直线,而高度为 0 的区域将显示为水平线。
package main
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
)
func main() {
myApp := app.New()
w := myApp.NewWindow("Line")
color := color.NRGBA{R: 255, G: 0, B: 180, A: 255}
line := canvas.NewLine(color)
line.StrokeWidth = 5
w.SetContent(line)
w.Resize(fyne.NewSize(100, 100))
w.ShowAndRun()
}
线条通常用于自定义布局或手动控制。与文本不同,它们没有自然(最小)大小,但可以在复杂的布局中发挥出色的效果。
canvas.Circle
定义由指定颜色填充的圆形。您还可以设置 a StrokeWidth
,因此设置 a 不同 StrokeColor
,如本例所示。
圆圈将填充由调用Resize()
或由其控制的布局指定的空间。由于示例将圆圈设置为窗口内容,它将在基本填充(由主题控制)内调整大小以填充窗口。
package main
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
)
func main() {
myApp := app.New()
w := myApp.NewWindow("Circle")
color := color.NRGBA{R: 255, G: 0, B: 180, A: 255}
circle := canvas.NewCircle(color)
circle.StrokeColor = color
circle.StrokeWidth = 5
w.SetContent(circle)
w.Resize(fyne.NewSize(100, 100))
w.ShowAndRun()
}
Acanvas.Image
表示 Fyne 中的可缩放图像资源。它可以从资源(如示例中所示)、图像文件、包含图像的 URI 位置、内存中的io.Reader
或 Goimage.Image
中加载。
默认图像填充模式canvas.ImageFillStretch
将导致它填充指定的空间(通过Resize()
或布局)。或者,您可以使用canvas.ImageFillContain
来确保保持纵横比并且图像在边界内。除此之外,您还可以使用canvas.ImageFillOriginal
(如此处示例中使用的)确保它的最小尺寸也等于原始图像尺寸。
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/theme"
)
func main() {
myApp := app.New()
w := myApp.NewWindow("Image")
image := canvas.NewImageFromResource(theme.FyneLogo())
// image := canvas.NewImageFromURI(uri)
// image := canvas.NewImageFromImage(src)
// image := canvas.NewImageFromReader(reader, name)
// image := canvas.NewImageFromFile(fileName)
image.FillMode = canvas.ImageFillOriginal
w.SetContent(image)
w.ShowAndRun()
}
图像可以是基于位图的(如 PNG 和 JPEG)或基于矢量的(如 SVG)。在可能的情况下,我们建议使用可缩放图像,因为它们将在尺寸发生变化时继续呈现良好状态。使用原始图像尺寸时要小心,因为它们可能不会在不同的用户界面比例下表现得完全符合预期。由于 Fyne 允许整个用户界面缩放,因此 25 像素的图像文件可能与 25 高度的 fyne 对象的高度不同。
esize()或布局)。或者,您可以使用
canvas.ImageFillContain来确保保持纵横比并且图像在边界内。除此之外,您还可以使用
canvas.ImageFillOriginal`(如此处示例中使用的)确保它的最小尺寸也等于原始图像尺寸。
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/theme"
)
func main() {
myApp := app.New()
w := myApp.NewWindow("Image")
image := canvas.NewImageFromResource(theme.FyneLogo())
// image := canvas.NewImageFromURI(uri)
// image := canvas.NewImageFromImage(src)
// image := canvas.NewImageFromReader(reader, name)
// image := canvas.NewImageFromFile(fileName)
image.FillMode = canvas.ImageFillOriginal
w.SetContent(image)
w.ShowAndRun()
}
图像可以是基于位图的(如 PNG 和 JPEG)或基于矢量的(如 SVG)。在可能的情况下,我们建议使用可缩放图像,因为它们将在尺寸发生变化时继续呈现良好状态。使用原始图像尺寸时要小心,因为它们可能不会在不同的用户界面比例下表现得完全符合预期。由于 Fyne 允许整个用户界面缩放,因此 25 像素的图像文件可能与 25 高度的 fyne 对象的高度不同。