用 Go 写了一个桌面程序:生成授权码的小工具,先看下效果,我已经安装到 macOS 上了。
它是通过 Fyne
实现的。
Fyne
是一款用于构建跨平台图形用户界面 (GUI) 的 Go 语言工具包。
它可以在 Windows、macOS、Linux 以及移动平台(iOS 和 Android)上运行。
Fyne
以简洁的 API 和优雅的设计而著称,使用现代风格的控件和主题系统,适合快速构建漂亮的桌面和移动应用。
1. 安装 Fyne
要开始使用 Fyne
,首先需要在你的 Go 环境中安装它:
go get fyne.io/fyne/v2
同时,Fyne
依赖系统上必须安装的图形和音频库。具体安装方法请参考 Fyne 官方文档:https://developer.fyne.io/started/installation。
2. 基本示例:创建一个简单的 Fyne 应用
Fyne
的基础是一个 app
对象和一个 window
对象。下面是一个创建简单窗口的示例:
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget"
)
func main() {
// 创建一个 Fyne 应用
myApp := app.New()
// 创建一个窗口
myWindow := myApp.NewWindow("Hello Fyne")
// 创建一个标签并将其添加到窗口
label := widget.NewLabel("Hello, Fyne!")
myWindow.SetContent(container.NewVBox(label))
// 显示并运行窗口
myWindow.ShowAndRun()
}
运行这个程序会弹出一个包含文本标签的窗口。
3. 组件(控件)
Fyne
提供了丰富的控件,用于构建不同类型的用户界面组件。下面列出了一些常用控件以及它们的使用方式:
3.1 按钮 (Button
)
button := widget.NewButton("Click Me", func() {
fmt.Println("Button clicked")
})
3.2 标签 (Label
)
label := widget.NewLabel("This is a label")
3.3 输入框 (Entry
)
entry := widget.NewEntry()
entry.SetPlaceHolder("Enter text...")
3.4 多行文本框 (MultiLineEntry
)
multiLineEntry := widget.NewMultiLineEntry()
multiLineEntry.SetPlaceHolder("Enter multi-line text...")
3.5 选择框 (Select
)
selectBox := widget.NewSelect([]string{"Option 1", "Option 2", "Option 3"}, func(value string) {
fmt.Println("Selected:", value)
})
3.6 切换开关 (Check
)
check := widget.NewCheck("Enable feature", func(checked bool) {
fmt.Println("Checked:", checked)
})
3.7 进度条 (ProgressBar
)
progress := widget.NewProgressBar()
progress.SetValue(0.5) // 设置进度 50%
4. 布局系统
Fyne
提供了多种布局管理器,用于灵活地组织界面上的控件。常用的布局有以下几种:
4.1 垂直盒子布局 (VBox
)
将组件垂直排列:
myWindow.SetContent(container.NewVBox(
widget.NewLabel("Label 1"),
widget.NewLabel("Label 2"),
))
4.2 水平盒子布局 (HBox
)
将组件水平排列:
myWindow.SetContent(container.NewHBox(
widget.NewLabel("Label 1"),
widget.NewLabel("Label 2"),
))
4.3 网格布局 (Grid
)
创建一个网格布局,可以指定列数:
myWindow.SetContent(container.NewGridWithColumns(2,
widget.NewLabel("Label 1"),
widget.NewLabel("Label 2"),
widget.NewLabel("Label 3"),
widget.NewLabel("Label 4"),
))
5. 窗口管理
5.1 设置窗口大小
myWindow.Resize(fyne.NewSize(400, 300))
5.2 设置窗口位置
myWindow.CenterOnScreen()
5.3 模态对话框
Fyne
提供了多种对话框,如消息框、文件选择框等:
dialog.ShowInformation("Title", "This is an information dialog", myWindow)
6. 事件处理
Fyne
的控件普遍支持事件处理,例如按钮的点击事件、文本框的输入事件等。
button := widget.NewButton("Click Me", func() {
fmt.Println("Button clicked")
})
7. 自定义主题
Fyne
允许你创建自定义主题,控制应用中组件的外观。你可以实现 fyne.Theme
接口来创建自定义主题:
package main
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/theme"
"image/color"
)
type myTheme struct{}
func (myTheme) BackgroundColor() color.Color { return color.RGBA{0, 128, 255, 255} }
func (myTheme) ButtonColor() color.Color { return color.RGBA{0, 255, 128, 255} }
// 实现其他需要的 theme 方法...
func main() {
myApp := app.New()
myApp.Settings().SetTheme(myTheme{})
myWindow := myApp.NewWindow("Custom Theme")
myWindow.ShowAndRun()
}
8. 画布与图形
Fyne
提供了 canvas
包,可以绘制图形、显示图像、文本等。
8.1 绘制矩形
rect := canvas.NewRectangle(color.RGBA{0, 128, 255, 255})
rect.SetMinSize(fyne.NewSize(100, 100))
myWindow.SetContent(container.NewCenter(rect))
8.2 显示图像
img := canvas.NewImageFromFile("path/to/image.png")
img.FillMode = canvas.ImageFillContain
myWindow.SetContent(container.NewCenter(img))
9. 数据绑定
Fyne
提供了数据绑定的特性,使得 UI 控件能够绑定到数据源,并在数据更新时自动刷新界面。
9.1 简单数据绑定
import "fyne.io/fyne/v2/data/binding"
str := binding.NewString()
str.Set("Initial value")
label := widget.NewLabelWithData(str)
entry := widget.NewEntryWithData(str)
10. 构建与打包
Fyne
提供了简单的构建和打包工具,使应用可以在不同平台上运行。
10.1 构建桌面应用
go build -o myapp main.go
10.2 使用 fyne
工具打包
安装 fyne
命令行工具:
go install fyne.io/fyne/v2/cmd/fyne@latest
打包应用:
fyne package -os windows -icon myicon.png
11. 移动与 Web 平台支持
Fyne
可以构建移动应用(iOS、Android)以及 Web 应用。详细指南请参考 Fyne 官方文档:https://developer.fyne.io/。
12. 手势和事件处理
Fyne
提供了对用户手势和事件的支持,例如拖动、点击、滚动等。这对于触摸屏设备或者需要自定义事件处理的场景非常实用。
12.1 手势处理
你可以使用 fyne.Draggable
接口在组件上添加拖动手势。
package main
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/widget"
)
type draggableRectangle struct {
canvas.Rectangle
}
func (d *draggableRectangle) Dragged(e *fyne.DragEvent) {
d.Move(fyne.NewPos(e.Position.X, e.Position.Y))
}
func (d *draggableRectangle) DragEnd() {
// Handle drag end event if needed
}
func main() {
myApp := app.New()
myWindow := myApp.NewWindow("Draggable Rectangle")
rect := &draggableRectangle{Rectangle: *canvas.NewRectangle(fyne.NewColorWithAlpha(0, 128, 0, 255))}
rect.Resize(fyne.NewSize(100, 100))
myWindow.SetContent(container.NewMax(rect))
myWindow.ShowAndRun()
}
12.2 支持鼠标事件
可以使用 desktop.Mouseable
接口来处理鼠标事件(例如鼠标移动、点击):
type mouseableLabel struct {
widget.Label
}
func (m *mouseableLabel) MouseIn(*desktop.MouseEvent) {
m.Text = "Mouse entered"
m.Refresh()
}
func (m *mouseableLabel) MouseOut() {
m.Text = "Mouse left"
m.Refresh()
}
func (m *mouseableLabel) MouseMoved(*desktop.MouseEvent) {
// Handle mouse move event if needed
}
13. 图标与资源管理
Fyne
提供了简单的图标与资源管理,可以在应用中使用内嵌图标、图片等资源。你可以使用 go:embed
来嵌入资源到应用程序中,或者使用 fyne.StaticResource
将文件嵌入到应用中。
13.1 使用内嵌资源
//go:embed assets/icon.png
var iconData []byte
icon := fyne.NewStaticResource("icon.png", iconData)
myApp.SetIcon(icon)
13.2 使用内置图标
Fyne
也提供了一组内置图标,如文件图标、删除图标、确认图标等。可以直接在按钮、对话框中使用:
button := widget.NewButtonWithIcon("Delete", theme.DeleteIcon(), func() {
fmt.Println("Delete button clicked")
})
14. 自定义小部件(组件)
如果 Fyne
的内置控件不能满足需求,你可以通过继承和组合现有控件来创建自定义小部件。
14.1 创建自定义小部件
下面是一个自定义计数器控件的例子:
type counter struct {
widget.Label
count int
}
func newCounter() *counter {
c := &counter{}
c.ExtendBaseWidget(c)
c.SetText("Count: 0")
return c
}
func (c *counter) increment() {
c.count++
c.SetText(fmt.Sprintf("Count: %d", c.count))
}
你可以为自定义小部件添加方法,绑定事件等。
15. 异步任务处理
Fyne
通过 fyne.CurrentApp().SendNotification
支持异步任务处理,以避免在 UI 主线程上执行耗时操作。
15.1 使用协程执行异步任务
go func() {
// 耗时操作
time.Sleep(2 * time.Second)
// 更新 UI
fyne.CurrentApp().SendNotification(&fyne.Notification{
Title: "Async Task",
Content: "Task completed!",
})
}()
16. 键盘快捷键
Fyne
支持全局和局部键盘快捷键,用于提升用户体验。
16.1 添加快捷键
可以通过实现 fyne.Shortcutable
接口来响应全局快捷键:
myWindow.Canvas().AddShortcut(&desktop.CustomShortcut{
KeyName: fyne.KeyN,
Modifier: fyne.KeyModifierControl,
}, func(shortcut fyne.Shortcut) {
fmt.Println("Ctrl+N pressed")
})
17. 拖放操作
在 Fyne
中,你可以通过实现 DragDrop
接口为控件添加拖放功能。
17.1 拖放文件
你可以为 window
添加文件拖放事件:
myWindow := myApp.NewWindow("Drag & Drop")
myWindow.Canvas().SetOnDragged(func(e *fyne.DragEvent) {
fmt.Printf("Dragged to position: %v\n", e.Position)
})
18. 插件支持
Fyne
提供插件支持,你可以加载外部资源,如字体、语言包等,实现更加丰富的功能。插件支持使得应用具有更强的扩展性。
19. 多窗口支持
Fyne
支持在应用中创建和管理多个窗口,这对于构建复杂的桌面应用非常有用。
19.1 创建和显示新窗口
newWindow := myApp.NewWindow("New Window")
newWindow.SetContent(widget.NewLabel("This is a new window"))
newWindow.Show()
20. 数据持久化
Fyne
提供了简单的数据持久化接口,可以在应用中存储用户设置、状态等数据。
20.1 使用 Preferences 存储数据
prefs := fyne.CurrentApp().Preferences()
prefs.SetString("username", "user123")
name := prefs.String("username")
fmt.Println("Stored username:", name)
21. 响应式设计
Fyne
支持响应式设计,它会根据窗口大小自动调整布局。在构建桌面和移动应用时,这一特性尤为重要。
myWindow.Resize(fyne.NewSize(600, 400))
myWindow.SetContent(container.NewVBox(
widget.NewLabel("Resizable window"),
))
22. 移动设备特性
在构建移动应用时,Fyne
支持使用手势和触控特性,并提供了针对移动设备的 UI 控件。
最后
最后咱们总结一下,提供的强大且实用的特性,包括但不限于:
丰富的控件:包括按钮、标签、输入框、选择框等。
多样化的布局管理器:支持垂直、水平、网格等多种布局方式。
事件处理:包括鼠标、键盘事件,手势识别等。
自定义主题:允许开发者自定义应用的外观。
画布与图形支持:绘制图形、显示图片等。
数据绑定:轻松绑定 UI 控件和数据源。
多窗口支持:可以在应用中创建和管理多个窗口。
插件支持:加载外部资源以扩展应用功能。
响应式设计:根据窗口大小自动调整界面布局。
移动设备特性:支持手势和触控操作,适用于构建移动应用。
快捷键支持:通过键盘快捷键提升用户体验。
异步任务:提供任务调度和通知功能,避免阻塞 UI。
拖放操作:支持文件和控件的拖放操作。
这些特性使得它在 Go 语言的 GUI 开发中具有很高的灵活性和实用性,无论是构建桌面应用还是移动应用,都能快速搭建功能齐全的界面。
感兴趣的,可以折腾起来了 ~
最后,谢谢你看到了这里👏 想要第一时间接收到推送,可以点个关注。
可点击下方👇 关注公众号
添加微信 👇 获取源码