Go-GTK 信号处理
信号处理
简介
现在我们已经把按钮添加到窗口中了,但是有一个问题:点击按钮没有反应。我们既然添加的是按钮,肯定希望当我们点击一个按钮时,能够做一些事情,这就用到了信号处理。
学习图形界面编程,我们会经常接触到“信号”这个名词。GTK中的“信号”实际上是一种软件中断。“中断”在我们生活中经常遇到,譬如,我正在房间里打游戏,突然送快递的来了,把正在玩游戏的我给“中断”了,我去签收快递( 处理中断 ),处理完成后,再继续玩我的游戏。GTK中的“信号”就是属于这么一种“中断”,当用户按下按钮的时候,就产生一个“中断”,相当于产生一个信号,接着就会处理这么一个“中断任务”(程序里体验为调用一个函数)。
按钮中常用的信号:
信号标识 | 触发条件 |
---|---|
"clicked" | 按下按钮且松开鼠标时触发(鼠标必须在按钮范围中) |
"pressed" | 按下按钮时(还没有松开鼠标)触发 |
"released" | 释放按钮时(无论在哪松开鼠标)触发 |
信号注册
对于程序而言,我们按下按钮,其实就是调用一个函数来对信号进行处理。假如有函数A, B, C,我们如何确定按下按钮后只调用函数A,而不是函数 B 或 C。这时候,我们需要一种规则规定,按下按钮后就调用函数A。
我们通过控件的Connect()方法来处理对应的信号。
Connect() 方法说明:
func (v *Widget) Connect(s string, f interface{}, datas ...interface{}) int
功能:信号注册
参数:
- v:信号发出者。可以认为我们操作的控件,如按下按钮,这个就是按钮指针
- s:信号标志,如:"clicked"
- f:回调函数的名称
- datas:给回调函数传的参数。尽管是可变参数,但是只能传递一个参数,可变参数的目的是为了让用户多个选择(可以传参,或者不传)
返回值:注册函数的标志
示例程序
下面通过代码实现一个按钮的 clicked
信号,其它两个请自行测试效果。
package main
import (
"fmt"
"github.com/mattn/go-gtk/glib"
"github.com/mattn/go-gtk/gtk"
"os"
)
func main(){
//GTK初始化操作
gtk.Init(&os.Args)
// 通过GTK创建窗口
win := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
// 设置窗体的大小
win.SetSizeRequest(640, 480)
// 设置窗体标题
win.SetTitle("GTK窗口")
// 创建按钮
b := gtk.NewButton()
// 设置按钮大小
b.SetSizeRequest(80, 32)
// 设置按钮内容
b.SetLabel("点击")
// 设置按钮点击事件
b.Connect("clicked", BtnClick, "点我干嘛~")
// 创建布局
layout := gtk.NewFixed()
// 将按钮 b 添加到布局中
layout.Add(b)
// 放在布局的指定位置
layout.Put(b, 0, 0)
// 移动按钮的位置,必须先Put(),再用Move()
layout.Move(b, 280, 224)
// 将布局放在界面中显示
win.Add(layout)
// 将界面显示
win.ShowAll()
// 调用GTK下的main运行程序
gtk.Main()
}
// 按钮 b 信号处理的回调函数
func BtnClick(ctx *glib.CallbackContext){
// 获取用户传递的参数,空接口类型
arg := ctx.Data()
// 对数据进行类型断言
data, ok := arg.(string)
// 如果 ok == true,说明类型断言正确
if ok{
fmt.Println(data)
}
}
或者可以通过匿名函数来实现:
package main
import (
"fmt"
"github.com/mattn/go-gtk/glib"
"github.com/mattn/go-gtk/gtk"
"os"
)
func main(){
//GTK初始化操作
gtk.Init(&os.Args)
// 通过GTK创建窗口
win := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
// 设置窗体的大小
win.SetSizeRequest(640, 480)
// 设置窗体标题
win.SetTitle("GTK窗口")
// 创建按钮
b := gtk.NewButton()
// 设置按钮大小
b.SetSizeRequest(80, 32)
// 设置按钮内容
b.SetLabel("点击")
// 设置按钮点击事件
// b.Connect("clicked", BtnClick, "点我干嘛~")
// 使用匿名函数实现按钮点击事件处理
b.Connect("clicked", func(ctx *glib.CallbackContext){
// 获取用户传递的参数,空接口类型
arg := ctx.Data()
// 对数据进行类型断言
data, ok := arg.(string)
// 如果 ok == true,说明类型断言正确
if ok{
fmt.Println(data)
}
}, "点我干嘛~")
// 创建布局
layout := gtk.NewFixed()
// 将按钮 b 添加到布局中
layout.Add(b)
// 放在布局的指定位置
layout.Put(b, 0, 0)
// 移动按钮的位置,必须先Put(),再用Move()
layout.Move(b, 280, 224)
// 将布局放在界面中显示
win.Add(layout)
// 将界面显示
win.ShowAll()
// 调用GTK下的main运行程序
gtk.Main()
}
运行结果:
李培冠博客
欢迎访问我的个人网站:
李培冠博客:lpgit.com