• 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

  • 相关阅读:
    Java微信公众平台开发(一)--接入微信公众平台
    微信开发准备
    微信公众平台开发前言
    Spring------自动化装配Bean(三)
    Spring------自动化装配Bean(二)
    Spring------自动化装配Bean(一)
    单链表的基本操作
    线性表的基本操作
    Apache Hadoop各版本发布的SVN地址
    configuration on ubuntu server
  • 原文地址:https://www.cnblogs.com/lpgit/p/13423609.html
Copyright © 2020-2023  润新知