Go版GTK:常用事件—绘图事件

GTK界面只要有图片的地方,其底层实际上是通过绘图实现的 。绘图实际上也是事件的一种,GTK中,绘图事件也叫曝光事件 。绘图的操作需要放在事件回调函数里 。
1 绘图触发条件
绘图时所触发的信号:-event 。只要触发曝光事件信号”-event”,就会自动调用所连接的回调函数 。
这里需要注意的是,曝光事件信号 “-event” 默认的情况下,是自动触发的(当然也可以人为触发),就算我们不作任何操作,”-event”信号也有可能自动触发 。前面我们学习中,我们按一下按钮就人为触发 “” 信号,按一下鼠标人为触发 “-press-event” 信号,如果我们不操作按钮,不操作鼠标,其对应的信号永远不会触发 。
窗口状态(移动,初始化,按按钮……)改变,只用我们肉眼能看到窗口上有变化,它都会自动触发曝光事件信号”-event”,然后就自动会调用它所连接的回调函数,但是,它不是刷新窗口的全部区域,它是按需要局部刷新,哪儿变化了就刷新那个变化的区域 。
当然我们也可以人为触发曝光事件信号”-event”:
func (v *Widget) QueueDraw()

Go版GTK:常用事件—绘图事件

文章插图
2 绘图API
窗口默认不允许在其上面绘图,需要人为设置:
window.SetAppPaintable(true)
绘图操作:
//指定窗口为绘图区域,在窗口上绘图painter := window.GetWindow().GetDrawable()gc := gdk.NewGC(painter)//bk:绘图的pixbuf,需要提前指定宽度和高度//x, y:画图的起点(相对于窗口而言)//其它参数为固定写法painter.DrawPixbuf(gc, bk, 0, 0, x, y, -1, -1, gdk.RGB_DITHER_NONE, 0, 0)
3 示例程序
glade设计如下:
Go版GTK:常用事件—绘图事件

文章插图
示例代码:
package mainimport ("fmt""os""github.com/mattn/go-gtk/gdk""github.com/mattn/go-gtk/gdkpixbuf""github.com/mattn/go-gtk/gtk")func main() {gtk.Init(&os.Args)builder := gtk.NewBuilder()//新建builderbuilder.AddFromFile("test.glade") //读取glade文件window := gtk.WindowFromObject(builder.GetObject("window1")) //获取窗口控件window.SetSizeRequest(480, 320)//设置窗口大小window.SetAppPaintable(true)//允许窗口能绘图(重要)var w, h int //保存窗口的宽度和高度//改变窗口大小时,触发"configure-event",然后手动刷新绘图区域,否则图片会重叠window.Connect("configure-event", func() {window.QueueDraw() //刷新绘图区域//获取窗口的宽度和高度window.GetSize(&w, &h)fmt.Println(w, h)})x := 0 //画笑脸起点//绘图(曝光)事件,其回调函数做绘图操作window.Connect("expose-event", func() {//指定窗口为绘图区域,在窗口上绘图painter := window.GetWindow().GetDrawable()gc := gdk.NewGC(painter)//设置背景图的pixbuf,其宽高和窗口一样,最后一个参数固定为falsebk, _ := gdkpixbuf.NewPixbufFromFileAtScale("./image/bk.jpg", w, h, false)//设置笑脸的pixbuf,其宽高为50,最后一个参数固定为falseface, _ := gdkpixbuf.NewPixbufFromFileAtScale("./image/face.png", 50, 50, false)//画图//bk:需要绘图的pixbuf,第5、6个参数为画图的起点(相对于窗口而言)//第3、4个参数习惯为0,第7、8个参数为-1则按pixbuf原来的尺寸绘图//gdk.RGB_DITHER_NONE不用抖动,最后2个参数习惯写0painter.DrawPixbuf(gc, bk, 0, 0, 0, 0, -1, -1, gdk.RGB_DITHER_NONE, 0, 0)painter.DrawPixbuf(gc, face, 0, 0, x, 100, -1, -1, gdk.RGB_DITHER_NONE, 0, 0)//释放pixbuf资源bk.Unref()face.Unref()})button := gtk.ButtonFromObject(builder.GetObject("button1")) //获取窗口控件//按钮"clicked"信号处理button.Clicked(func() {x += 50 //增加笑脸起点坐标if x >= w { //如果超过窗口宽度,置0x = 0}window.QueueDraw() //刷新绘图区域})//按窗口关闭按钮,自动触发"destroy"信号window.Connect("destroy", gtk.MainQuit)window.ShowAll()gtk.Main()}