golang开发GUI桌面应用(一)

基础操作

requires:Go 1.11.x or later

安装依赖

go get github.com/lxn/walk
go get github.com/akavel/rsrc
rsrc
go-gui/gui.go
package main

import (
	"strings"

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

func main() {
	var inTE, outTE *walk.TextEdit
	MainWindow{
		Title: "xiaochuan测试",
		MinSize: Size{600, 400},
		Layout: VBox{},
		Children: []Widget{
			HSplitter{
				Children: []Widget{
					TextEdit{AssignTo: &inTE, MaxLength: 10},
					TextEdit{AssignTo: &outTE, ReadOnly: true},
				},
			},
			PushButton{
				Text: "SCREAM",
				OnClicked: func() {
					outTE.SetText(strings.ToUpper(inTE.Text()))
				},
			},
		},
	}.Run()
}
go mod init go-gui
manifestgo-gui/go-gui.exe.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
        </dependentAssembly>
    </dependency>
    <application xmlns="urn:schemas-microsoft-com:asm.v3">
        <windowsSettings>
            <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
            <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True</dpiAware>
        </windowsSettings>
    </application>
</assembly>
rsrc -manifest go-gui.exe.manifest -o rsrc.syso
go build -ldflags="-H windowsgui"
go-gui.exe

在这里插入图片描述

go-gui.exemanifest

添加图标

rsrc -manifest go-gui.exe.manifest -ico favicon.ico -o rsrc.syso
go build -ldflags="-H windowsgui"
favicon.ico

在这里插入图片描述
运行程序,任务栏上的图标也变成了这个。

具体说明

1、manifest 文件

这个东西的作用就是为了解决 以前windows上的“Dll 地狱” 问题才产生的新的DLL管理解决方案。大家知道,Dll是动态加载共享库,同一个Dll可能被多个程序所使用,而所谓“Dll 地狱”就是当不通程序依赖的Dll相同,但版本不同时,由于系统不能分辨到底哪个是哪个,所以加载错了Dll版本,然后就挂了。于是盖茨就吸取了教训,搞了一个程序集清单的东西,每个程序都要有一个清单,这个清单存再和自己应用程序同名的.manifest文件中,里面列出其所需要的所有依赖,这儿所列出的依赖可不是简单地靠文件明来区分的,而是根据一种叫做“强文件名”的东西区分的。。。。。。

2、rsrc程序的作用
rsrc - Tool for embedding binary resources in Go programs.

Generates a .syso file with specified resources embedded in .rsrc section,
  aimed for consumption by Go linker when building Win32 excecutables.

The generated *.syso files should get automatically recognized by 'go build'
command and linked into an executable/library, as long as there are any *.go
files in the same directory.

OPTIONS:
  -arch string
    	architecture of output file - one of: 386, amd64, [EXPERIMENTAL: arm, arm64] (default "amd64")
  -ico string
    	comma-separated list of paths to .ico files to embed
  -manifest string
    	path to a Windows manifest file to embed
  -o string
    	name of output COFF (.res or .syso) file; if set to empty, will default to 'rsrc_windows_{arch}.syso'
rsrcsysosyso

在Go1.16起引入了embed包,也可以实现将静态文件编译进去。参考:https://www.php.cn/be/go/484192.html

本机安装的是Go1.14,没有办法演示使用 embed 的方式加载 manifest 文件。

manifestgui.gogo-gui.exe.manifestgo build -ldflags="-H windowsgui"go-gui.exemanifestgo-gui.exe.manifestgo-gui.exego-gui.exego-gui.exe.manifest
-ldflags="-H windowsgui"

正常情况下,任何语言开发的GUI都会伴随着一个CMD框在后面,比如这样

在这里插入图片描述

go build-ldflags="-H windowsgui"

这个CMD框的作用是打印信息,输出等。

-ldflags="-H windowsgui -w"

关于 golang GUI

win
win把win32 api几乎所有相关的声明都导成了go。如果发现有没导出的,可以参照里面的方法导出,很简单的。

walk
是对win包的再次封装,方便使用。

fyne
文档相对丰富一些。