go gui 控制項和信號 控制項 控制項簡介 控制項是對數據和方法的封裝。控制項有自己的屬性和方法。屬性是指控制項的特征。方法是指控制項的一些簡單而可見的功能。如按鈕就是一個控制項,這個按鈕是方形的,裡面有張圖片,這是我們能看到外觀屬性,同時,這個按鈕具備被人按下的功能。 GTK中控制項主要分為兩類:容器控制項,非容 ...
go-gui-控制項和信號
控制項
控制項簡介
控制項是對數據和方法的封裝。控制項有自己的屬性和方法。屬性是指控制項的特征。方法是指控制項的一些簡單而可見的功能。如按鈕就是一個控制項,這個按鈕是方形的,裡面有張圖片,這是我們能看到外觀屬性,同時,這個按鈕具備被人按下的功能。
GTK中控制項主要分為兩類:容器控制項,非容器控制項。
容器控制項:它可以容納別的控制項,我們可以理解為盒子,盒子拿來裝東西。容器控制項又分為兩類,一類只能容納一個控制項,如視窗,按鈕;另一類能容納多個控制項,如佈局控制項。
非容器控制項:它不可以容納別的控制項,如標簽、行編輯。
package main
import (
"os"
"github.com/mattn/go-gtk/gtk"
)
func main() {
gtk.Init(&os.Args) //環境初始化
//--------------------------------------------------------
// 主視窗
//--------------------------------------------------------
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL) //創建視窗
window.SetPosition(gtk.WIN_POS_CENTER) //設置視窗居中顯示
window.SetTitle("GTK Go!") //設置標題
window.SetSizeRequest(300, 200) //設置視窗的寬度和高度
//--------------------------------------------------------
// GtkFixed
//--------------------------------------------------------
layout := gtk.NewFixed() //創建固定佈局
//--------------------------------------------------------
// GtkButton
//--------------------------------------------------------
b1 := gtk.NewButton() //新建按鈕
b1.SetLabel("^_@") //設置內容
//b1.SetSizeRequest(100, 50) //設置按鈕大小
b2 := gtk.NewButtonWithLabel("@_~") //新建按鈕,同時設置內容
b2.SetSizeRequest(100, 50) //設置按鈕大小
//--------------------------------------------------------
// 添加佈局、添加容器
//--------------------------------------------------------
window.Add(layout) //把佈局添加到主視窗中
layout.Put(b1, 0, 0) //設置按鈕在容器的位置
layout.Move(b1, 50, 50) //移動按鈕的位置,必須先put,再用move
layout.Put(b2, 50, 100)
window.ShowAll() //顯示所有的控制項
gtk.Main() //主事件迴圈,等待用戶操作
}
//func (v *Fixed) Put(w IWidget, x, y int)
//功能:固定佈局容器添加控制項
//參數:
// widget:要添加的控制項
// x, y:控制項擺放位置的起點坐標
信號
GTK採用了信號與回調函數來處理視窗外部傳來的事件、消息或信號。當信號發生時,程式自動調用為信號連接(註冊)的回調函數。
學習圖形界面編程,我們會經常接觸到“信號”這個名詞。GTK中的“信號”實際上是一種軟體中斷。“中斷”在我們生活中經常遇到,譬如,我正在房間里打游戲,突然送快遞的來了,把正在玩游戲的我給“中斷”了,我去簽收快遞( 處理中斷 ),處理完成後,再繼續玩我的游戲。GTK中的“信號”就是屬於這麼一種“中斷”,當用戶按下按鈕的時候,就產生一個“中斷”,相當於產生一個信號,接著就會處理這麼一個“中斷任務”(程式里體驗為調用一個函數)。
“信號”在GTK中可以認為一種中斷的標誌,如按下按鈕的標誌為”pressed”,釋放按鈕的標誌為”released”,這些標誌就相當於 go 語言的關鍵字一樣,我們使用的時候必須完全按照它的名字來寫。需要註意的是,每個控制項的信號標誌不一定都一樣,如按鈕(GtkButton)里有”pressed”信號,視窗(GtkWindow)里就沒這個信號,每個控制項具體有哪個信號,應該查看幫助文檔來確定。
信號標識 觸發條件
“clicked” 按下按鈕時觸發
“pressed” 按下按鈕時觸發
“released” 釋放按鈕時觸發
package main
import (
"fmt"
"os"
"github.com/mattn/go-gtk/glib"
"github.com/mattn/go-gtk/gtk"
)
//按鈕b1信號處理的回調函數
func HandleButton(ctx *glib.CallbackContext) {
arg := ctx.Data() //獲取用戶傳遞的參數,是空介面類型
p, ok := arg.(*int) //類型斷言
if ok { //如果ok為true,說明類型斷言正確
fmt.Println("*p = ", *p) //用戶傳遞傳遞的參數為&tmp,是一個變數的地址
*p = 250 //操作指針所指向的記憶體
}
fmt.Println("按鈕b1被按下")
//gtk.MainQuit() //關閉gtk程式
}
func main() {
gtk.Init(&os.Args) //環境初始化
//--------------------------------------------------------
// 主視窗
//--------------------------------------------------------
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL) //創建視窗
window.SetPosition(gtk.WIN_POS_CENTER) //設置視窗居中顯示
window.SetTitle("GTK Go!") //設置標題
window.SetSizeRequest(300, 200) //設置視窗的寬度和高度
//--------------------------------------------------------
// GtkFixed
//--------------------------------------------------------
layout := gtk.NewFixed() //創建固定佈局
//--------------------------------------------------------
// GtkButton
//--------------------------------------------------------
b1 := gtk.NewButton() //新建按鈕
b1.SetLabel("^_@") //設置內容
//b1.SetSizeRequest(100, 50) //設置按鈕大小
b2 := gtk.NewButtonWithLabel("@_~") //新建按鈕,同時設置內容
b2.SetSizeRequest(100, 50) //設置按鈕大小
//--------------------------------------------------------
// 添加佈局、添加容器
//--------------------------------------------------------
window.Add(layout) //把佈局添加到主視窗中
layout.Put(b1, 0, 0) //設置按鈕在容器的位置
layout.Move(b1, 50, 50) //移動按鈕的位置,必須先put,再用move
layout.Put(b2, 50, 100)
//--------------------------------------------------------
// 信號處理
//--------------------------------------------------------
//按鈕按下自動觸發"pressed",自動調用HandleButton, 同時將 &tmp 傳遞給HandleButton
tmp := 10
b1.Connect("pressed", HandleButton, &tmp)
//回調函數為匿名函數,推薦寫法
//按鈕按下自動觸發"pressed",自動調用匿名函數,
b2.Connect("pressed", func() {
fmt.Println("b2被按下")
fmt.Println("tmp = ", tmp)
}) //註意:}和)在同一行
window.ShowAll() //顯示所有的控制項
gtk.Main() //主事件迴圈,等待用戶操作
}
//func (v *Widget) Connect(s string, f interface{}, datas ...interface{}) int
//功能:信號註冊
//參數:
// v: 信號發出者,可以認為我們操作的控制項,如按下按鈕,這個就為按鈕指針
// s:信號標誌,如"pressed"
// f:回調函數的名稱,
// datas:給回調函數傳的參數,儘管是可變參數,但是只能傳遞一個參數,可變參數的目的為了讓用戶多個選擇(可以傳參,或者不傳)
//返回值:
// 註冊函數的標誌
glade的簡單使用
package main
import (
"fmt"
"os"
"github.com/mattn/go-gtk/gtk"
)
func main() {
gtk.Init(&os.Args)
builder := gtk.NewBuilder() //新建builder
builder.AddFromFile("test.glade") //讀取glade文件
// 獲取視窗控制項指針,註意"window1"要和glade里的標誌名稱匹配
window := gtk.WindowFromObject(builder.GetObject("window1"))
b1 := gtk.ButtonFromObject(builder.GetObject("123456")) //獲取按鈕1
b2 := gtk.ButtonFromObject(builder.GetObject("togglebutton1")) //獲取按鈕2
//信號處理
b1.Connect("clicked", func() {
//獲取按鈕內容
fmt.Println("button txt = ", b1.GetLabel())
})
b2.Connect("clicked", func() {
//獲取按鈕內容
fmt.Println("button txt = ", b2.GetLabel())
gtk.MainQuit() //關閉視窗
})
//按視窗關閉按鈕,自動觸發"destroy"信號
window.Connect("destroy", gtk.MainQuit)
window.ShowAll()
gtk.Main()
}
//可以簡單分為兩步:
//1)讀取glade文件
//// 創建GtkBuilder對象,GtkBuilder在<gtk/gtk.h>聲明
//GtkBuilder *builder = gtk_builder_new();
//// 讀取test.glade文件的信息,保存在builder指針變數里
//gtk_builder_add_from_file(builder, "./test.glade", NULL);
//2)獲取glade文件里的控制項
//// 獲取視窗控制項指針,註意"window1" 要和glade里的標誌名稱匹配
//GtkWidget *window = GTK_WIDGET(gtk_builder_get_object (builder, "window1"));