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

GTK界面只要有图片的地方,其底层实际上是通过绘图实现的。绘图实际上也是事件的一种,GTK中,绘图事件也叫曝光事件。绘图的操作需要放在事件回调函数里

1 绘图触发条件

绘图时所触发的信号:expose-event。只要触发曝光事件信号”expose-event”,就会自动调用所连接的回调函数。

这里需要注意的是,曝光事件信号 “expose-event” 默认的情况下,是自动触发的(当然也可以人为触发),就算我们不作任何操作,”expose-event”信号也有可能自动触发。前面我们学习中,我们按一下按钮就人为触发 “clicked” 信号,按一下鼠标人为触发 “button-press-event” 信号,如果我们不操作按钮,不操作鼠标,其对应的信号永远不会触发。

窗口状态(移动,初始化,按按钮……)改变,只用我们肉眼能看到窗口上有变化,它都会自动触发曝光事件信号”expose-event”,然后就自动会调用它所连接的回调函数,但是,它不是刷新窗口的全部区域,它是按需要局部刷新,哪儿变化了就刷新那个变化的区域。

当然我们也可以人为触发曝光事件信号”expose-event”:

func (v *Widget) QueueDraw()

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设计如下:
这里写图片描述

示例代码:

package main

import (
    "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()       //新建builder
    builder.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,其宽高和窗口一样,最后一个参数固定为false
        bk, _ := gdkpixbuf.NewPixbufFromFileAtScale("./image/bk.jpg", w, h, false)
        //设置笑脸的pixbuf,其宽高为50,最后一个参数固定为false
        face, _ := gdkpixbuf.NewPixbufFromFileAtScale("./image/face.png", 50, 50, false)

        //画图
        //bk:需要绘图的pixbuf,第5、6个参数为画图的起点(相对于窗口而言)
        //第3、4个参数习惯为0,第7、8个参数为-1则按pixbuf原来的尺寸绘图
        //gdk.RGB_DITHER_NONE不用抖动,最后2个参数习惯写0
        painter.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 { //如果超过窗口宽度,置0
            x = 0
        }

        window.QueueDraw() //刷新绘图区域
    })

    //按窗口关闭按钮,自动触发"destroy"信号
    window.Connect("destroy", gtk.MainQuit)

    window.ShowAll()

    gtk.Main()
}

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值