Go語言版黑白棋(三):背景圖、最小化、關閉窗口

功能說明

這裏寫圖片描述

設置一張背景圖,增加2個按鈕:最小化、關閉窗口。

glade界面設計

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

示例代碼

package main

import (
    "fmt"
    "os"
    "unsafe"

    "github.com/mattn/go-gtk/gdk"
    "github.com/mattn/go-gtk/gdkpixbuf"
    "github.com/mattn/go-gtk/glib"
    "github.com/mattn/go-gtk/gtk"
)

//控件結構體
type ChessWidet struct {
    window      *gtk.Window //窗口
    buttonMin   *gtk.Button //最小化按鈕
    buttonClose *gtk.Button //關閉按鈕
}

//屬性結構體
type ChessInfo struct {
    w, h int //窗口的寬度高度
    x, y int //鼠標點擊座標(相對於窗口)

}

type Chessboard struct {
    //匿名字段
    ChessWidet
    ChessInfo
}

//函數,給按鈕設置圖片
func ButtonSetImageFromFile(button *gtk.Button, filename string) {
    //獲取按鈕的寬度和高度
    var w, h int
    button.GetSizeRequest(&w, &h)
    //獲取pixbuf,指定其大小
    pixbuf, _ := gdkpixbuf.NewPixbufFromFileAtScale(filename, w-10, h-10, false)

    //通過pixbuf新建image
    image := gtk.NewImageFromPixbuf(pixbuf)
    //按鈕設置圖片
    button.SetImage(image)

    //釋放資源
    pixbuf.Unref()
}

//Chessboard的方法,獲取控件,設置控件屬性,返回主窗口控件指針
func (obj *Chessboard) CreateWindow() *gtk.Window {
    builder := gtk.NewBuilder()     //新建builder
    builder.AddFromFile("ui.glade") //讀取glade文件

    //獲取glade對應的控件
    obj.window = gtk.WindowFromObject(builder.GetObject("window1"))      //獲取窗口控件
    obj.buttonMin = gtk.ButtonFromObject(builder.GetObject("buttonMin")) //按鈕
    obj.buttonClose = gtk.ButtonFromObject(builder.GetObject("buttonClose"))

    //設置屬性
    //窗口屬性
    obj.w = 800
    obj.h = 480
    obj.window.SetSizeRequest(obj.w, obj.h)    //設置窗口大小
    obj.window.SetPosition(gtk.WIN_POS_CENTER) //居中顯示
    obj.window.SetAppPaintable(true)           //允許窗口能繪圖(重要)
    obj.window.SetDecorated(false)             //去表框
    //添加鼠標按下事件
    obj.window.SetEvents(int(gdk.BUTTON_PRESS_MASK | gdk.BUTTON1_MOTION_MASK))

    //按鈕屬性
    ButtonSetImageFromFile(obj.buttonMin, "image/min.png") //給按鈕設置圖片,此爲自定義函數
    ButtonSetImageFromFile(obj.buttonClose, "image/close.png")
    obj.buttonMin.SetCanFocus(false) //去掉按鈕上的聚焦框
    obj.buttonClose.SetCanFocus(false)

    return obj.window
}

//繪圖事件處理函數,"expose-event"的回調函數
func PaintEvent(ctx *glib.CallbackContext) {
    arg := ctx.Data()            //獲取用戶傳遞的參數,是空接口類型
    obj, ok := arg.(*Chessboard) //類型斷言
    if false == ok {             //如果ok爲false,說明類型斷言錯誤
        fmt.Println("arg.(*Chessboard) err")
        return
    }

    //指定窗口爲繪圖區域,在窗口上繪圖
    painter := obj.window.GetWindow().GetDrawable()
    gc := gdk.NewGC(painter)

    //設置背景圖的pixbuf,其寬高和窗口一樣,最後一個參數固定爲false
    bg, _ := gdkpixbuf.NewPixbufFromFileAtScale("./image/bg.jpg", obj.w, obj.h, false)

    //畫圖,畫背景圖
    painter.DrawPixbuf(gc, bg, 0, 0, 0, 0, -1, -1, gdk.RGB_DITHER_NONE, 0, 0)

    //釋放資源
    bg.Unref()
}

//鼠標按下事件處理,MousePressEvent爲其回調函數,把obj傳遞給回調函數
func MousePressEvent(ctx *glib.CallbackContext) {
    arg := ctx.Data()            //獲取用戶傳遞的參數,是空接口類型
    obj, ok := arg.(*Chessboard) //類型斷言
    if false == ok {             //如果ok爲false,說明類型斷言錯誤
        fmt.Println("arg.(*Chessboard) err")
        return
    }

    //獲取鼠鍵按下屬性結構體變量,系統內部的變量,不是用戶傳參變量
    tmp := ctx.Args(0)
    event := *(**gdk.EventButton)(unsafe.Pointer(&tmp))
    if event.Button == 1 { //左鍵
        obj.x, obj.y = int(event.X), int(event.Y) //保存點擊的起點座標
    }
}

//方法,事件、信號處理,回調函數如果簡單使用匿名函數,否則自定義函數
func (obj *Chessboard) HandleSignal() {

    //鼠標按下事件處理,MousePressEvent爲其回調函數,把obj傳遞給回調函數
    obj.window.Connect("button-press-event", MousePressEvent, obj)

    //鼠標移動事件處理,實現窗口的移動
    obj.window.Connect("motion-notify-event", func(ctx *glib.CallbackContext) {
        //獲取鼠標屬性結構體變量,系統內部的變量,不是用戶傳參變量
        arg := ctx.Args(0)
        //還是EventButton
        event := *(**gdk.EventButton)(unsafe.Pointer(&arg))

        //移動窗口
        obj.window.Move(int(event.XRoot)-obj.x, int(event.YRoot)-obj.y)
    })

    //改變窗口大小時,觸發"configure-event",然後手動刷新繪圖區域,否則圖片會重疊
    obj.window.Connect("configure-event", func() {
        obj.window.QueueDraw() //刷新繪圖區域
    })

    //繪圖(曝光)事件,其回調函數PaintEvent做繪圖操作,把obj傳遞給回調函數
    obj.window.Connect("expose-event", PaintEvent, obj)

    //最小化按鈕信號處理
    obj.buttonMin.Connect("clicked", func() {
        obj.window.Iconify() //窗口最小化
    })

    //關閉按鈕信號處理
    obj.buttonClose.Connect("clicked", func() {
        gtk.MainQuit() //程序結束
    })
}

func main() {
    gtk.Init(&os.Args)

    var obj Chessboard //創建結構體變量

    //創建控件,設計屬性
    window := obj.CreateWindow()

    //事件、信號處理
    obj.HandleSignal()

    //顯示控件
    window.ShowAll()

    gtk.Main()
}

程序運行效果:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章