GO-圖形使用者介面
阿新 • • 發佈:2018-11-10
圖形使用者介面1:初識Walk
Go與GUI——GO語言的圖形介面Walk
GO沒有原生的介面庫,所以不能直接用來寫GUI介面。但最近網際網路上已經湧現出不少成熟、好用的第三方介面庫。使用它們,就同樣可以寫出同C#、C++的介面。而且效率還更勝一籌。
關於Walk介面庫(官方介紹):Walk是一個寫給Golang的Window應用程式庫套件,它主要用於桌面GUI的開發,但也有更多的東西。
安裝Walk
在瀏覽這部分前,請確定已經配置安裝完畢go語言的環境。如果沒有,可以參考go官網的Install幫助。另外,注意:這個Walk庫只能執行在Go 1.1.x及以上。
要安裝Walk很簡單,只要執行命令:go get github.com/lxn/walk
等待命令執行完畢,這時候檢查GOPATH的src與pkg下,是否有符合自己計算機環境的walk目錄。(我的電腦的CPU架構為AMD64,則會在%GOPATH%\windows_amd64\github.com\lxn
下出現一個walk資料夾與編譯完成的a檔案,另外在%GOPATH%\src\github.com\lxn
下也會出現walk的原始碼)
我們還要安裝一個工具rsrc,以完成後期的打包工作,執行命令:go get github.com/akavel/rsrc
等待命令執行完成,然後檢查,步驟與上文相仿,不再多說。
例項
匯入依賴
import (
//引入walk包
"github.com/lxn/walk"
//declarative包下包含大量控制元件,加一個點:使用包內的成員時可以省略包名
."github.com/lxn/walk/declarative"
"strings"
)
- 官方的入門Demo
func main() { //宣告兩個文字域控制元件 var inTE, outTE *walk.TextEdit //配置主視窗,並執行起來 MainWindow{ //視窗標題 Title: "尖叫的Demo", //可拉伸的最小尺寸 MinSize: Size{600, 400}, //主佈局:垂直佈局 Layout: VBox{}, //視窗中的所有控制元件 Children: []Widget{ //水平分割器(水平小布局) HSplitter{ //區域性水平排列的控制元件們 Children: []Widget{ //文字輸入框 TextEdit{ //繫結到inTE變數 AssignTo: &inTE}, //文字輸出框 TextEdit{ AssignTo: &outTE, //只讀的文字框 ReadOnly: true}, }, }, //普通按鈕 PushButton{ //按鈕文字 Text: "動動我試試", //響應函式 OnClicked: func() { inputStr := inTE.Text() outputStr := strings.ToUpper(inputStr) outTE.SetText(outputStr) }, }, }, }.Run() }
圖形使用者介面2:常用控制元件
認識幾種常用控制元件
- 按鈕
- 選單
- 工具欄
- 介面佈局
- 列表
- 顯示圖片
匯入依賴
import (
"github.com/lxn/walk"
. "github.com/lxn/walk/declarative"
"os"
"strings"
"io/ioutil"
"fmt"
"log"
)
定義全域性資料
// 全域性應用的選單項
var myAction *walk.Action
//自定義的主視窗
var myWindow *MyMainWindow
//自定義視窗
type MyMainWindow struct {
*walk.MainWindow
te *walk.TextEdit
//listbox使用的資料
model *EnvModel
//listbox控制元件
listBox *walk.ListBox
}
定義列表資料模型
//環境變數條目資料模型
type EnvItem struct {
//環境變數的名字和值
name string
value string
}
//列表資料模型
type EnvModel struct {
//繼承ListModelBase
walk.ListModelBase
//環境變數數集合
items []EnvItem
}
//列表資料模型的工廠方法
func NewEnvModel() *EnvModel {
env := os.Environ()
m := &EnvModel{items: make([]EnvItem, len(env))}
for i, e := range env {
j := strings.Index(e, "=")
if j == 0 {
continue
}
name := e[0:j]
value := strings.Replace(e[j+1:], ";", "\r\n", -1)
m.items[i] = EnvItem{name, value}
}
return m
}
定義列表相關的監聽和系統回撥介面
//定義列表專案的單擊監聽
func (mw *MyMainWindow) lb_CurrentIndexChanged() {
i := mw.listBox.CurrentIndex()
item := &mw.model.items[i]
mw.te.SetText(item.value)
fmt.Println("CurrentIndex: ", i)
fmt.Println("CurrentEnvVarName: ", item.name)
}
//定義列表專案的雙擊監聽
func (mw *MyMainWindow) lb_ItemActivated() {
value := mw.model.items[mw.listBox.CurrentIndex()].value
walk.MsgBox(mw, "Value", value, walk.MsgBoxIconInformation)
}
//列表的系統回撥方法:獲得listbox的資料長度
func (m *EnvModel) ItemCount() int {
return len(m.items)
}
//列表的系統回撥方法:根據序號獲得資料
func (m *EnvModel) Value(index int) interface{} {
return m.items[index].name
}
定義普通事件回撥
//顯示訊息視窗
func ShowMsgBox(title, msg string) int {
return walk.MsgBox(myWindow, "天降驚喜", "你老婆跟人跑了!", walk.MsgBoxOK)
}
//一個普通的事件回撥函式
func TiggerFunc() {
ShowMsgBox("天降驚喜", "你老婆跟人跑了!")
}
主調函式
func main() {
defer func() {
if err := recover(); err != nil {
errMsg := fmt.Sprintf("%#v", err)
ioutil.WriteFile("fuck.log", []byte(errMsg), 0644)
}
}()
myWindow = &MyMainWindow{model: NewEnvModel()}
if _, err := (MainWindow{
AssignTo: &myWindow.MainWindow,
Title: "常用控制元件",
//視窗選單
MenuItems: []MenuItem{
//主選單一
Menu{
Text: "川菜",
//選單項
Items: []MenuItem{
//選單項一
Action{
AssignTo: &myAction,
Text: "魚香肉絲",
//選單圖片
Image: "img/open.png",
//快捷鍵
Shortcut: Shortcut{walk.ModControl, walk.KeyO},
OnTriggered: func() {
ShowMsgBox("已下單", "我是選單項")
},
},
//分隔線
Separator{},
//選單項二
Action{
//文字
Text: "水煮魚",
//響應函式
OnTriggered: func() {
ShowMsgBox("已下單", "您要的菜馬上就去買")
},
},
},
},
//主選單二
Menu{
Text: "粵菜",
//選單項
Items: []MenuItem{
//選單項一
Action{
Text: "魚香肉絲",
//選單圖片
Image: "img/open.png",
//快捷鍵
Shortcut: Shortcut{walk.ModControl, walk.KeyO},
OnTriggered: func() {
ShowMsgBox("已下單", "我是選單項")
},
},
//分隔線
Separator{},
//選單項二
Action{
//文字
Text: "水煮魚",
//響應函式
OnTriggered: func() {
ShowMsgBox("已下單", "您要的菜馬上就去買")
},
},
},
},
},
//工具欄
ToolBar: ToolBar{
//按鈕風格:圖片在字的前面
ButtonStyle: ToolBarButtonImageBeforeText,
//工具欄中的工具按鈕
Items: []MenuItem{
//引用現成的Action
ActionRef{&myAction},
Separator{},
//自帶子選單的工具按鈕
Menu{
//工具按鈕本身的圖文和監聽
Text: "工具按鈕2",
Image: "img/document-properties.png",
OnTriggered: TiggerFunc,
//附帶一個子選單
Items: []MenuItem{
Action{
Text: "X",
OnTriggered: TiggerFunc,
},
Action{
Text: "Y",
OnTriggered: TiggerFunc,
},
Action{
Text: "Z",
OnTriggered: TiggerFunc,
},
},
},
Separator{},
//普通工具按鈕
Action{
Text: "工具按鈕3",
Image: "img/system-shutdown.png",
OnTriggered: func() {
ShowMsgBox("天降驚喜", "你老婆跟人跑了!")
},
},
},
},
MinSize: Size{600, 400},
Layout: VBox{},
//控制元件們
Children: []Widget{
//水平區域性
HSplitter{
MinSize: Size{600, 300},
Children: []Widget{
ListBox{
StretchFactor: 1,
//賦值給myWindow.listBox
AssignTo: &myWindow.listBox,
//要顯示的資料
Model: myWindow.model,
//單擊監聽
OnCurrentIndexChanged: myWindow.lb_CurrentIndexChanged,
//雙擊監聽
OnItemActivated: myWindow.lb_ItemActivated,
},
TextEdit{
StretchFactor: 1,
AssignTo: &myWindow.te,
ReadOnly: true,
},
},
},
HSplitter{
MaxSize:Size{600,50},
Children: []Widget{
//影象
ImageView{
Background: SolidColorBrush{Color: walk.RGB(255, 191, 0)},
//圖片檔案位置
Image: "img/open.png",
//和四周的邊距
Margin: 5,
//定義最大拉伸尺寸
MinSize: Size{50, 50},
//顯示模式
Mode: ImageViewModeZoom,
},
//按鈕
PushButton{
StretchFactor:8,
Text: "摸我有驚喜",
OnClicked: func() {
ShowMsgBox("天降驚喜", "你老婆跟人跑了!")
},
},
},
},
},
}.Run()); err != nil {
log.Fatal(err)
}
}