Go语言版黑白棋(四):界面其它设计

功能说明

这里写图片描述

界面上增加3个标签,分别用于显示黑白子棋子个数,还有一个用于显示倒计时的时间。

还增加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 //关闭按钮
    labelBlack  *gtk.Label  //显示黑子个数
    labelWhite  *gtk.Label  //显示白子个数
    labelTime   *gtk.Label  //倒计时间显示
    imageBlack  *gtk.Image  //黑子image,用于提示该谁落子
    imageWhite  *gtk.Image  //白子image,用于提示该谁落子
}

//属性结构体
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()
}

//函数,给image设置图片
func ImageSetPixbufFromFile(image *gtk.Image, filename string) {
    //获取image的宽度和高度
    var w, h int
    image.GetSizeRequest(&w, &h)
    //获取pixbuf,指定其大小
    pixbuf, _ := gdkpixbuf.NewPixbufFromFileAtScale(filename, w-5, h-5, false)

    //image设置pixbuf
    image.SetFromPixbuf(pixbuf)

    //释放资源
    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.labelBlack = gtk.LabelFromObject(builder.GetObject("labelBlack")) //标签
    obj.labelWhite = gtk.LabelFromObject(builder.GetObject("labelWhite"))
    obj.labelTime = gtk.LabelFromObject(builder.GetObject("labelTime"))
    obj.imageBlack = gtk.ImageFromObject(builder.GetObject("imageBlack")) //image
    obj.imageWhite = gtk.ImageFromObject(builder.GetObject("imageWhite")) //image

    //设置属性
    //窗口属性
    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)

    //标签属性
    obj.labelBlack.ModifyFontSize(50) //修改字体大小
    obj.labelWhite.ModifyFontSize(50) //修改字体大小
    obj.labelTime.ModifyFontSize(30)  //修改字体大小

    //修改字体颜色为白色
    obj.labelBlack.ModifyFG(gtk.STATE_NORMAL, gdk.NewColor("white"))
    obj.labelWhite.ModifyFG(gtk.STATE_NORMAL, gdk.NewColor("white"))
    obj.labelTime.ModifyFG(gtk.STATE_NORMAL, gdk.NewColor("white"))

    //image属性
    ImageSetPixbufFromFile(obj.imageBlack, "image/black.png")
    ImageSetPixbufFromFile(obj.imageWhite, "image/white.png")

    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()
}

程序运行效果:
这里写图片描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页