go-gui-控件和信号
- 作者: 别人都说你是煤气罐成精
- 来源: 51数据库
- 2021-08-18
go-gui-控件和信号
控件
控件简介
控件是对数据和方法的封装。控件有自己的属性和方法。属性是指控件的特征。方法是指控件的一些简单而可见的功能。如按钮就是一个控件,这个按钮是方形的,里面有张图片,这是我们能看到外观属性,同时,这个按钮具备被人按下的功能。
gtk中控件主要分为两类:容器控件,非容器控件。
容器控件:它可以容纳别的控件,我们可以理解为盒子,盒子拿来装东西。容器控件又分为两类,一类只能容纳一个控件,如窗口,按钮;另一类能容纳多个控件,如布局控件。
非容器控件:它不可以容纳别的控件,如标签、行编辑。
package main
import (
"os"
"github.com/mattn/go-gtk/gtk"
)
func main() {
gtk.init(&os.args) //环境初始化
//--------------------------------------------------------
// 主窗口
//--------------------------------------------------------
window := gtk.newwindow(gtk.window_toplevel) //创建窗口
window.setposition(gtk.win_pos_center) //设置窗口居中显示
window.settitle("gtk go!") //设置标题
window.setsizerequest(300, 200) //设置窗口的宽度和高度
//--------------------------------------------------------
// gtkfixed
//--------------------------------------------------------
layout := gtk.newfixed() //创建固定布局
//--------------------------------------------------------
// gtkbutton
//--------------------------------------------------------
b1 := gtk.newbutton() //新建按钮
b1.setlabel("^_@") //设置内容
//b1.setsizerequest(100, 50) //设置按钮大小
b2 := gtk.newbuttonwithlabel("@_~") //新建按钮,同时设置内容
b2.setsizerequest(100, 50) //设置按钮大小
//--------------------------------------------------------
// 添加布局、添加容器
//--------------------------------------------------------
window.add(layout) //把布局添加到主窗口中
layout.put(b1, 0, 0) //设置按钮在容器的位置
layout.move(b1, 50, 50) //移动按钮的位置,必须先put,再用move
layout.put(b2, 50, 100)
window.showall() //显示所有的控件
gtk.main() //主事件循环,等待用户操作
}
//func (v *fixed) put(w iwidget, x, y int)
//功能:固定布局容器添加控件
//参数:
// widget:要添加的控件
// x, y:控件摆放位置的起点坐标
信号
gtk采用了信号与回调函数来处理窗口外部传来的事件、消息或信号。当信号发生时,程序自动调用为信号连接(注册)的回调函数。
学习图形界面编程,我们会经常接触到“信号”这个名词。gtk中的“信号”实际上是一种软件中断。“中断”在我们生活中经常遇到,譬如,我正在房间里打游戏,突然送快递的来了,把正在玩游戏的我给“中断”了,我去签收快递( 处理中断 ),处理完成后,再继续玩我的游戏。gtk中的“信号”就是属于这么一种“中断”,当用户按下按钮的时候,就产生一个“中断”,相当于产生一个信号,接着就会处理这么一个“中断任务”(程序里体验为调用一个函数)。
“信号”在gtk中可以认为一种中断的标志,如按下按钮的标志为”pressed”,释放按钮的标志为”released”,这些标志就相当于 go 语言的关键字一样,我们使用的时候必须完全按照它的名字来写。需要注意的是,每个控件的信号标志不一定都一样,如按钮(gtkbutton)里有”pressed”信号,窗口(gtkwindow)里就没这个信号,每个控件具体有哪个信号,应该查看帮助文档来确定。
信号标识 触发条件
“clicked” 按下按钮时触发
“pressed” 按下按钮时触发
“released” 释放按钮时触发
package main
import (
"fmt"
"os"
"github.com/mattn/go-gtk/glib"
"github.com/mattn/go-gtk/gtk"
)
//按钮b1信号处理的回调函数
func handlebutton(ctx *glib.callbackcontext) {
arg := ctx.data() //获取用户传递的参数,是空接口类型
p, ok := arg.(*int) //类型断言
if ok { //如果ok为true,说明类型断言正确
fmt.println("*p = ", *p) //用户传递传递的参数为&tmp,是一个变量的地址
*p = 250 //操作指针所指向的内存
}
fmt.println("按钮b1被按下")
//gtk.mainquit() //关闭gtk程序
}
func main() {
gtk.init(&os.args) //环境初始化
//--------------------------------------------------------
// 主窗口
//--------------------------------------------------------
window := gtk.newwindow(gtk.window_toplevel) //创建窗口
window.setposition(gtk.win_pos_center) //设置窗口居中显示
window.settitle("gtk go!") //设置标题
window.setsizerequest(300, 200) //设置窗口的宽度和高度
//--------------------------------------------------------
// gtkfixed
//--------------------------------------------------------
layout := gtk.newfixed() //创建固定布局
//--------------------------------------------------------
// gtkbutton
//--------------------------------------------------------
b1 := gtk.newbutton() //新建按钮
b1.setlabel("^_@") //设置内容
//b1.setsizerequest(100, 50) //设置按钮大小
b2 := gtk.newbuttonwithlabel("@_~") //新建按钮,同时设置内容
b2.setsizerequest(100, 50) //设置按钮大小
//--------------------------------------------------------
// 添加布局、添加容器
//--------------------------------------------------------
window.add(layout) //把布局添加到主窗口中
layout.put(b1, 0, 0) //设置按钮在容器的位置
layout.move(b1, 50, 50) //移动按钮的位置,必须先put,再用move
layout.put(b2, 50, 100)
//--------------------------------------------------------
// 信号处理
//--------------------------------------------------------
//按钮按下自动触发"pressed",自动调用handlebutton, 同时将 &tmp 传递给handlebutton
tmp := 10
b1.connect("pressed", handlebutton, &tmp)
//回调函数为匿名函数,推荐写法
//按钮按下自动触发"pressed",自动调用匿名函数,
b2.connect("pressed", func() {
fmt.println("b2被按下")
fmt.println("tmp = ", tmp)
}) //注意:}和)在同一行
window.showall() //显示所有的控件
gtk.main() //主事件循环,等待用户操作
}
//func (v *widget) connect(s string, f interface{}, datas ...interface{}) int
//功能:信号注册
//参数:
// v: 信号发出者,可以认为我们操作的控件,如按下按钮,这个就为按钮指针
// s:信号标志,如"pressed"
// f:回调函数的名称,
// datas:给回调函数传的参数,尽管是可变参数,但是只能传递一个参数,可变参数的目的为了让用户多个选择(可以传参,或者不传)
//返回值:
// 注册函数的标志
glade的简单使用
package main
import (
"fmt"
"os"
"github.com/mattn/go-gtk/gtk"
)
func main() {
gtk.init(&os.args)
builder := gtk.newbuilder() //新建builder
builder.addfromfile("test.glade") //读取glade文件
// 获取窗口控件指针,注意"window1"要和glade里的标志名称匹配
window := gtk.windowfromobject(builder.getobject("window1"))
b1 := gtk.buttonfromobject(builder.getobject("123456")) //获取按钮1
b2 := gtk.buttonfromobject(builder.getobject("togglebutton1")) //获取按钮2
//信号处理
b1.connect("clicked", func() {
//获取按钮内容
fmt.println("button txt = ", b1.getlabel())
})
b2.connect("clicked", func() {
//获取按钮内容
fmt.println("button txt = ", b2.getlabel())
gtk.mainquit() //关闭窗口
})
//按窗口关闭按钮,自动触发"destroy"信号
window.connect("destroy", gtk.mainquit)
window.showall()
gtk.main()
}
//可以简单分为两步:
//1)读取glade文件
//// 创建gtkbuilder对象,gtkbuilder在<gtk/gtk.h>声明
//gtkbuilder *builder = gtk_builder_new();
//// 读取test.glade文件的信息,保存在builder指针变量里
//gtk_builder_add_from_file(builder, "./test.glade", null);
//2)获取glade文件里的控件
//// 获取窗口控件指针,注意"window1" 要和glade里的标志名称匹配
//gtkwidget *window = gtk_widget(gtk_builder_get_object (builder, "window1"));
