go 的gui库比较多,但许多缺乏官方文档,学习起来有一定的困难。经过再三考虑,本人选择了其中的walk库进行学习,这个库只能运行在windows平台上。walk库的语法风格像JavaScript,可以快速构建gui程序,界面也美观。同时walk库利用反射实现了响应式,可以使界面中的值与变量双向绑定,十分方便。当然如果想做的十分美观,还是使用Qt。
本人学习是通过github上给的例子。按照一般gui库的学习思路进行整理。
创建基本的窗口可以在GitHub上找到例子
窗口
package main
import (
"github.com/lxn/walk"
. "github.com/lxn/walk/declarative"
"strings"
)
func main() {
var inTE, outTE *walk.TextEdit
MainWindow{
Title: "SCREAMO",
MinSize: Size{600, 400},
Layout: VBox{},
Children: []Widget{
HSplitter{
Children: []Widget{
TextEdit{AssignTo: &inTE},
TextEdit{AssignTo: &outTE, ReadOnly: true},
},
},
PushButton{
Text: "SCREAM",
OnClicked: func() {
outTE.SetText(strings.ToUpper(inTE.Text()))
},
},
},
}.Run()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
上面的程序创建了一个窗口,当然还需要rsrc.syso,这个文件用来索要一些权限,不需要改动。我们可以看到,使用结构体表达整个窗口的结构十分清晰。首先是窗口的标题,其次是窗口的最小的大小,之后是布局,这表明,将子组件垂直排列,当然在子组件内部还可以有子布局。之后定义窗口中的组件,一个水平分割器,两个文本框,他们将水平排列。紧接着下面有一个按钮,并定义了按钮上的文字和点击事件。这一切都十分简单清晰直观。
布局
walk的布局十分简单,但能解决大部分需求。
垂直布局
垂直布局就是将组件垂直排列,可以指定Margin,默认会有Margin。
package main
import (
. "github.com/lxn/walk/declarative"
)
func main() {
var mw = MainWindow{
Title:
"SCREAMO",
// 指定窗口的大小
MinSize: Size{Width: 600, Height: 400},
Layout: VBox{
},
Children: []Widget{
PushButton{Text: "btn1"},
PushButton{Text: "btn2"},
PushButton{Text: "btn3"},
PushButton{Text: "btn4"},
PushButton{Text: "btn5"},
},
}
mw.Persistent = true
mw.Run()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
水平排列
同理
格子布局
格子布局可以指定行和列的数量,也可以指定行或者列。
package main
import (
. "github.com/lxn/walk/declarative"
)
func main() {
var mw = MainWindow{
Title:
"SCREAMO",
// 指定窗口的大小
MinSize: Size{},
Layout: Grid{
Rows: 3,
},
Children: []Widget{
PushButton{Text: "btn1"},
PushButton{Text: "btn2"},
PushButton{Text: "btn3"},
PushButton{Text: "btn4"},
PushButton{Text: "btn5"},
},
}
mw.Persistent = true
mw.Run()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
指定组件占的列数和使用空白填充
package main
import (
. "github.com/lxn/walk/declarative"
)
func main() {
var mw = MainWindow{
Title:
"SCREAMO",
// 指定窗口的大小
MinSize: Size{},
Layout: Grid{
Columns: 5,
},
Children: []Widget{
PushButton{Text: "btn1",ColumnSpan: 2},
PushButton{Text: "btn2"},
PushButton{Text: "btn3"},
HSpacer{ColumnSpan: 3},
PushButton{Text: "btn4"},
PushButton{Text: "btn5"},
},
}
mw.Persistent = true
mw.Run()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
使用水平或垂直分割器
package main
import (
. "github.com/lxn/walk/declarative"
)
func main() {
var mw = MainWindow{
Title:
"SCREAMO",
// 指定窗口的大小
MinSize: Size{},
Layout: VBox{
MarginsZero: true,
},
Children: []Widget{
HSplitter{
Children: []Widget{
PushButton{Text: "btn1"},
PushButton{Text: "btn2"},
PushButton{Text: "btn3"},
},
},
VSeparator{
},
PushButton{Text: "btn4"},
PushButton{Text: "btn5"},
},
}
mw.Persistent = true
mw.Run()
}