Go Gio 實戰:煮蛋計時器的實現 01 — 空窗口
大家好,我是幽鬼。
接下來我們將一步步實通過 gio 實現一個煮蛋計時器。
這是完全從頭開始實現的,使用 Gio 這個 Go GUI 庫實現的獨立 Go 應用程序,會解釋每一個步驟。
實現的最終效果如下:
本系列大綱:
-
第 1 章 - 空窗口
-
第 2 章 - 標題和大小
-
第 3 章 - 按鈕
-
第 4 章 - 低按鈕(Low Button)
-
第 5 章 - 重構
-
第 6 章 - 帶邊距的按鈕
-
第 7 章 - 進度條
-
第 8 章 - 畫圓
-
第 9 章 畫雞蛋
-
第 10 章 - 輸入沸騰時間
先看如何實現一個空窗口。
01 目標
本節的目的是創建一個空白畫布,我們稍後可以在其上進行繪製。
An empty window
02 主要內容
本節代碼主要做三件事:
-
導入 Gio
-
創建並調用 goroutine:
-
創建一個新窗口:
w
-
啓動一個無限循環,等待窗口中的事件,具體事件後續實現
接下來看看具體的代碼。
03 代碼
package main
import (
"gioui.org/app"
)
func main() {
go func() {
// 創建一個新窗口(Window)
w := app.NewWindow()
// 監聽窗口的事件
for range w.Events() {
}
}()
app.Main()
}
04 代碼詳解
代碼看起來很簡單。不過,還是花點時間看看發生了什麼,畢竟 GUI 編程大家接觸的少。
1)我們導入了 gioui.org/app
,它幹什麼用的?
我們需要查看文檔:https://pkg.go.dev/gioui.org/app:
包 app 爲運行圖形用戶界面的操作系統功能提供了一個獨立於平臺的界面。
這是很棒的特性。Gio 爲我們處理所有與平臺相關的事情,這和 Go 一樣,是跨平臺的。
這可能比你意識到的要更重要。因爲,即使你今天的應用程序是單平臺的,但指不定哪天想遷移到其他平臺。
上篇文章簡單介紹了,Gio 對各個平臺都有支持,包括移動端,甚至 tvOS。
2)goroutine 中的事件循環
-
事件循環的代碼是:
for range w.Events()
,它循環監聽窗口中的事件。現在我們只是監聽,並沒有對事件做任何處理。後續章節會實現。從 app.Main[1] 我們瞭解到:
因爲 Main 在某些平臺上也是阻塞的,所以 Window 的事件循環必須在 goroutine 中運行。
有 Go 經驗的同學應該理解這塊內容。因爲如果 app.Main 不堵塞,最後 main 函數就返回,程序退出了。
-
一個沒有名字的 goroutine,即_匿名函數_,被創建並運行事件循環。由於它在 goroutine 中,它將與程序的其餘部分同時運行。
go func { // ... }()
這是 Go 語言常見的寫法。
3)最後上文提到的調用 app.Main()
啓動程序,app.Main 的文檔提到:
Main 函數必須從程序的 main 函數中調用,以便將主線程的控制權移交給需要它的操作系統。Main 的具體實現,不同系統不一樣。
比如 Unix、Windows 等系統,直接調用 select {},感興趣的可以查看 gio 的源碼。
不過,上面的簡單代碼,在 Mac 下運行不正常,會 panic:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x40f7f85]
可以先忽略。如果就想看看,可以用下面代碼:
package main
import (
"gioui.org/app"
"gioui.org/io/system"
"gioui.org/layout"
"gioui.org/op"
)
func main() {
go func() {
w := app.NewWindow()
var ops op.Ops
for e := range w.Events() {
switch e := e.(type) {
case system.FrameEvent:
gtx := layout.NewContext(&ops, e)
e.Frame(gtx.Ops)
}
}
}()
app.Main()
}
05 小結
通過 gio 創建 GUI 應用程序,和普通服務端應用程序類似:
-
一個循環,處理各種事件
-
一個堵塞,好比 select{} 或 HTTP 服務中的 http.ListenAndServe
趕緊動手試試吧!
參考資料
[1]
app.Main: https://pkg.go.dev/gioui.org/app#hdr-Main
歡迎關注「幽鬼」,像她一樣做團隊的核心。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/qgATId9egNlqqXTf3xC5Rg