Go之Walk框架详解

前言:在最近的开发过程中,我需要使用 Golang 完成数据处理任务。为了避免重复工作,并且考虑到同事也有类似需求,我决定利用 Walk 框架构建一个可视化的可执行程序,以提高工作效率。


Walk: 用 Go 语言开发轻量级 Windows GUI 框架

Walk 是一款基于 Go 语言开发的轻量级 GUI 框架,专注于构建 Windows 平台的桌面应用程序。它通过封装 Windows API,提供声明式的界面构建方式,支持常见的 GUI 组件和事件处理。


学习资源

备注 :最下方有Walk组件及属性详情,和示例代码。


框架特点

  1. 仅支持 Windows:Walk 是专注于 Windows 平台的 GUI 框架,无法用于跨平台开发。
  2. 声明式 UI:通过类似 HTML 的结构化方式定义界面,代码清晰易读。
  3. 丰富的组件:支持窗口、按钮、标签、文本框、列表、表格、菜单等常用组件。
  4. 事件驱动:通过回调函数处理用户交互事件,逻辑直观简单。
  5. 轻量高效:直接基于 Windows API,性能优异,适合追求高效的本地应用开发。

适用场景

  • 快速开发 Windows 工具或管理程序。
  • 需要直接调用 Windows API 的高性能场景。
  • 针对单一平台的桌面应用程序开发。

与跨平台 GUI 框架(如 Qt、Electron)相比,Walk 更加轻量,适合小型项目或对性能要求较高的本地化应用。


优缺点分析

优点:

  • 轻量高效: 基于 Windows API,性能优异。
  • 简洁直观: 声明式 UI 定义方式更贴近 Go 的开发习惯。
  • 快速上手: 学习成本低,适合小型项目。

缺点:

  • 仅限 Windows: 无法满足跨平台需求。
  • 功能有限: 对复杂动画和现代 GUI 特效支持较弱。
  • 文档较少: 社区支持和生态相对较弱。

安装与环境配置

在开始之前,请确保以下内容已准备好:

安装 Go 开发环境

如果尚未安装 Go,请访问 Go 官方下载页面 下载并安装最新版本(建议使用 Go 1.18 或更高版本)。

配置 Go 环境变量

安装完成后,确保环境变量配置正确:

  • 在终端中运行 go version,确认安装成功。

  • 配置

    GOPATH
    

    GOROOT
    

    ,例如:

    export GOPATH=$HOME/go
    export PATH=$PATH:$GOPATH/bin
    

安装 Walk 和相关依赖

使用以下命令安装 Walk 和 Windows API 相关的依赖库:

go get github.com/lxn/walk
go get github.com/lxn/win

这些库用于开发 Windows GUI 应用程序。


创建清单文件 (test.manifest)

创建一个名为 test.manifest 的文件,内容为以下 XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
    应用程序清单文件
    本清单指定了:
    - 使用版本为 6.0.0.0 的 Microsoft Windows 公共控件,以支持现代化 UI。
    - 启用 DPI 感知,改善高分辨率显示器的显示效果。
    - 启用管理员权限,以获得更高的权限访问。
-->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
    <!-- 程序的程序集标识 -->
    <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>
    
    <!-- 依赖 Microsoft Windows 公共控件 -->
    <dependency>
        <dependentAssembly>
            <assemblyIdentity 
                type="win32" 
                name="Microsoft.Windows.Common-Controls" 
                version="6.0.0.0" 
                processorArchitecture="*" 
                publicKeyToken="6595b64144ccf1df" 
                language="*"/>
        </dependentAssembly>
    </dependency>
    
    <!-- 应用程序设置 -->
    <asmv3:application>
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
            <!-- 启用 DPI 感知,改善高分辨率显示器的缩放体验 -->
            <dpiAware>true</dpiAware>
        </asmv3:windowsSettings>
    </asmv3:application>
    
    <!-- 请求管理员权限 -->
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges>
                <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
            </requestedPrivileges>
        </security>
    </trustInfo>
</assembly>

编译清单文件为资源文件

使用 rsrc 工具将清单文件编译为 .syso 格式的资源文件:

安装 rsrc 工具

在终端中运行以下命令安装工具:

go get github.com/akavel/rsrc
编译清单文件

运行以下命令:

rsrc -manifest test.manifest -o rsrc.syso

这会生成一个 rsrc.syso 文件,供 go build 使用。

或者直接分发清单文件

可以将 test.manifest 重命名为 test.exe.manifest,与生成的可执行文件 test.exe 一起分发。


构建应用程序

确保应用程序的 Go 源代码(如 test.go)位于当前目录,然后运行以下命令:

go build

如果需要隐藏控制台窗口(适用于 GUI 应用程序),运行以下命令:

go build -ldflags="-H windowsgui"

运行应用程序

执行生成的 test.exe 文件即可运行应用程序。


核心组件与结构

Walk 的核心组件分为以下几类

  1. 窗口(Window):包括主窗口(MainWindow)和对话框(Dialog)。
  2. 布局(Layout):支持水平布局(HBox)、垂直布局(VBox)和表格布局(GridView)。
  3. 控件(Widget):如按钮(Button)、标签(Label)、文本框(LineEdit)等。
  4. 事件(Event Handling):通过回调函数处理事件,例如按钮点击或文本变化。

Walk 组件详解:

1. 窗口类组件
组件 描述
MainWindow 应用程序主窗口。
Dialog 模态对话框窗口。
ToolBar 工具栏,可以包含按钮或其他控件。

2. 布局类组件
组件 描述
VBox 垂直布局,子控件按从上到下排列。
HBox 水平布局,子控件按从左到右排列。
Grid 网格布局,子控件按行列排列。
Composite 复合组件,用于包含其他控件,同时支持自定义布局。

3. 输入类组件
组件 描述
PushButton 按钮,用于触发点击事件。
LineEdit 单行文本输入框。
TextEdit 多行文本输入框。
CheckBox 复选框,用于布尔选择。
RadioButton 单选按钮,属于单选组。
ComboBox 下拉选择框,用于从列表中选择一个值。
SpinBox 数值选择框,可增加或减少数值。
Slider 滑块,用于调整数值。

4. 显示类组件
组件 描述
Label 文本标签,用于显示静态文本。
ImageView 图像视图,用于显示图片。
ProgressBar 进度条,用于显示任务进度。
LinkLabel 超链接标签,支持跳转功能。

5. 数据展示类组件
组件 描述
TableView 表格视图,用于展示二维数据,支持排序和选择。
TreeView 树形视图,用于显示分层数据。
ListBox 列表框,用于显示一维数据。

6. 容器类组件
组件 描述
ScrollView 滚动视图,用于包含较大内容,支持滚动。
TabWidget 标签页容器,用于分组内容。
GroupBox 分组框,用于逻辑分组控件,通常带标题。

7. 其他组件
组件 描述
Splitter 分隔控件,用于调整子控件大小。
HSpacer 水平间距控件,用于调整布局的空白距离。
VSpacer 垂直间距控件,用于调整布局的空白距离。

Walk 组件属性详解:

属性 类型 描述
Title string 设置窗口的标题,通常显示在窗口的标题栏上。
Size Size 设置窗口的初始大小,包含 WidthHeight 子属性,用于分别指定宽度和高度。
MinSize Size 设置窗口的最小尺寸,包含 WidthHeight 子属性,确保窗口无法缩小到小于指定的尺寸。
Layout Layout 设置窗口的布局管理器,常见的布局管理器有 VBox(垂直布局)、HBox(水平布局)、Grid(网格布局)等。
Children []Widget 定义窗口中的子控件,这是一个控件列表(如按钮、标签、文本框等),根据设置的布局进行排列。
Width int 设置控件的宽度。
Height int 设置控件的高度。
Text string 设置控件的文本内容,常用于标签、按钮等文本显示控件。
OnClicked func() 设置按钮等控件的点击事件处理函数。
Enabled bool 设置控件是否可用,true 表示可用,false 表示禁用。
Visible bool 设置控件是否可见,true 表示可见,false 表示不可见。
Checked bool 设置复选框或单选按钮的选中状态。
MaxSize Size 设置窗口的最大尺寸,确保窗口无法放大到大于指定的尺寸。
Menu Menu 设置窗口的菜单栏,通常包含多个菜单项。
Icon Icon 设置窗口的图标,通常在任务栏中显示。
ToolBar ToolBar 设置窗口中的工具栏,通常包含按钮或其他控件。
Focus Widget 设置窗口或控件的默认焦点控件,即当窗口打开时,首先获取焦点的控件。
Style Style 设置控件的样式,例如按钮的外观或文本框的样式。
TabOrder int 设置控件在 Tab 键切换时的顺序。

备注Size 是一个包含 WidthHeight 的结构体,Layout 是一个布局管理器,Children 是包含窗口控件的列表。


示例代码

1. 简单窗口示例

以下是一个带有按钮的基本窗口示例:

package main

import (
	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
)

func main() {
	var mainWindow *walk.MainWindow

	MainWindow{
		AssignTo: &mainWindow,
		Title:    "Hello Walk",
		Size:     Size{Width: 400, Height: 300},
		Layout:   VBox{},
		Children: []Widget{
			Label{Text: "Welcome to Walk GUI!"},
			PushButton{
				Text: "Click Me",
				OnClicked: func() {
					walk.MsgBox(mainWindow, "Message", "Button Clicked!", walk.MsgBoxIconInformation)
				},
			},
		},
	}.Run()
}

运行效果:

  • 窗口标题为 "Hello Walk",包含一个标签和一个按钮。
  • 点击按钮会弹出一条消息框显示 "Button Clicked!"。

2. 表单与输入框示例

创建一个简单的表单,用户填写姓名后点击按钮显示欢迎消息:

package main

import (
	"fmt"
	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
)

func main() {
	var mainWindow *walk.MainWindow
	var nameEdit *walk.LineEdit

	MainWindow{
		AssignTo: &mainWindow,
		Title:    "Form Example",
		Size:     Size{Width: 400, Height: 200},
		Layout:   VBox{},
		Children: []Widget{
			Label{Text: "Enter your name:"},
			LineEdit{AssignTo: &nameEdit},
			PushButton{
				Text: "Submit",
				OnClicked: func() {
					name := nameEdit.Text()
					walk.MsgBox(mainWindow, "Welcome", fmt.Sprintf("Hello, %s!", name), walk.MsgBoxIconInformation)
				},
			},
		},
	}.Run()
}

运行效果:

  • 窗口包含一个输入框和一个按钮。
  • 用户输入姓名后,点击按钮会弹出欢迎消息。

3. 表格与数据绑定示例

以下示例展示如何创建一个表格控件并绑定数据:

package main

import (
	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
)

type Person struct {
	Name  string
	Age   int
	Email string
}

func main() {
	var mainWindow *walk.MainWindow

	people := []Person{
		{Name: "Alice", Age: 30, Email: "alice@example.com"},
		{Name: "Bob", Age: 25, Email: "bob@example.com"},
		{Name: "Charlie", Age: 35, Email: "charlie@example.com"},
	}

	MainWindow{
		AssignTo: &mainWindow,
		Title:    "Table Example",
		Size:     Size{Width: 600, Height: 400},
		Layout:   VBox{},
		Children: []Widget{
			TableView{
				Columns: []TableViewColumn{
					{Title: "Name", Width: 150},
					{Title: "Age", Width: 50},
					{Title: "Email", Width: 200},
				},
				Model: walk.NewReflectTableModel(people),
			},
		},
	}.Run()
}

运行效果:

  • 表格显示包含 Name、Age 和 Email 的数据。
  • 数据从 people 切片中加载,支持动态更新。
相关推荐
江木12313 分钟前
CUDA C 编程入门学习记录
c语言·开发语言·学习
sin220131 分钟前
springboot之YAML语法
java·spring boot·后端
不知名美食探索家33 分钟前
【10】Golang实用且神奇的开发操作总结
服务器·开发语言·golang
鹿屿二向箔1 小时前
搭建一个基于Spring Boot的书籍学习平台
spring boot·后端·学习
2401_897908311 小时前
2019-Android-高级面试题总结-从java语言到AIDL使用与原理
android·java·开发语言
fancc椰2 小时前
STL—stack与queue
开发语言·c++
咔咔库奇2 小时前
【three.js】纹理贴图
开发语言·javascript·three.js·贴图·three
mikey棒棒棒2 小时前
RabbitMQ-消息可靠性以及延迟消息
java·开发语言·中间件·rabbitmq·消息可靠性·死信交换机·惰性队列
MasterNeverDown2 小时前
RabbitMQ踩坑- RabbitMQ service is already present
开发语言·后端
m0_672449602 小时前
Java日志配置
java·开发语言·单元测试