控件是對數據和方法的封裝。控件有本身的屬性和方法。屬性是指控件的特徵。方法是指控件的一些簡單而可見的功能。如按鈕就是一個控件,這個按鈕是方形的,裏面有張圖片,這是咱們能看到外觀屬性,同時,這個按鈕具有被人按下的功能。git
GTK中控件主要分爲兩類:容器控件,非容器控件。github
容器控件:它能夠容納別的控件,咱們能夠理解爲盒子,盒子拿來裝東西。容器控件又分爲兩類,一類只能容納一個控件,如窗口,按鈕;另外一類能容納多個控件,如佈局控件。
非容器控件:它不能夠容納別的控件,如標籤、行編輯。編程
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」 釋放按鈕時觸發ui
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:給回調函數傳的參數,儘管是可變參數,可是隻能傳遞一個參數,可變參數的目的爲了讓用戶多個選擇(能夠傳參,或者不傳) //返回值: // 註冊函數的標誌
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"));