五张图了解golang GUI编程
代码整理
package main
import "os"
//import "os/exec"
//import "fmt"
import "github.com/mattn/go-gtk/gtk"
import "github.com/mattn/go-gtk/glib"
func Handl(ctx *glib.CallbackContext) {
//fmt.Println("hhhhhhhh")
}
func main() {
//初始化
gtk.Init(&os.Args)
builder := gtk.NewBuilder()
builder.AddFromFile("./test.glade")
win := gtk.WindowFromObject(builder.GetObject("window"))
win.Show()
//用户写的代码
win := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
win.SetTitle("GO GTK")
win.SetSizeRequest(420, 380)
layout := gtk.NewFixed()
win.Add(layout)
win.SetIconFromFile("./并行并发.png")
b := gtk.NewButtonWithLabel("*_*")
b.SetSizeRequest(100, 100)
layout.Put(b, 0, 100)
b.Connect("clicked", Handl, "gggg")
win.ShowAll()
win.SetDefaultSize(100, 100)
win.Connect("destroy", func() {
//fmt.Println("+++++")
gtk.MainQuit()
})
//主事件循环
gtk.Main()
//fmt.Println("关闭了呢")
}
package main
import (
"fmt"
"os"
"github.com/mattn/go-gtk/glib"
"github.com/mattn/go-gtk/gtk"
)
func main() {
//1.初始化
gtk.Init(&os.Args) //固定初始化准备的环境
//2.用户写的代码
//a.创建窗口
//b.设置窗口属性(标题,大小)
//c.显示窗口
win := gtk.NewWindow(gtk.WINDOW_TOPLEVEL) //带边框的顶层窗口
win.SetTitle("go gtk") //设置标题
win.SetSizeRequest(480, 320) //设置窗口大小
//显示
//创建容器控件(固定布局,任意布局)
//布局添加到窗口上
//创建按钮
//按钮添加到布局中
//显示控件
layout := gtk.NewFixed()
win.Add(layout) //把布局添加到窗口上
b1 := gtk.NewButtonWithLabel("^_^")
b2 := gtk.NewButtonWithLabel("@_@")
b2.SetSizeRequest(100, 100) //设置按钮2大小
layout.Put(b1, 0, 0) //0,0坐标
layout.Put(b2, 50, 50)
//win.Show()
//layout.Show()
//b1.Show()
//b2.Show()
win.ShowAll() //多个控件,用代码创建的控件需要showall
//信号处理
//按钮按下触发的信号:clicked
str := "are you ok?"
b1.Connect("clicked", HandleSignal, str)
//麻烦,处理函数可以是匿名函数,推荐写法
/*b2.Connect("clicked", func() {
fmt.Println("222222222222")
})*/
b2.Clicked(func() { //Clicked做了封装,更加简洁
fmt.Println("222222222222")
})
//按窗口的关闭按钮,触发"destroy"
win.Connect("destroy", func() {
fmt.Println("窗口被关闭了")
gtk.MainQuit() //gtk程序关闭
})
//告诉系统,只要按下按钮,自动调用HandleSignal,str是给HandleSignal的函数
//Connect()只会调用一次,告诉系统一个规则,只要告诉一次就够了
//3.主事件循环(固定)
//a 让程序不结束,b 等待用户操作(移动窗口、点击鼠标)
//1.3.基本固定
gtk.Main() //阻塞
fmt.Println("over")
}
func HandleSignal(ctx *glib.CallbackContext) { //注意参数写法,
//fmt.Println(ctx.Data()) //获取用户传递的数据,空接口类型
arg := ctx.Data()
data, ok := arg.(string) //类型断言,反推回原始数据的类型
if ok {
fmt.Printf("按钮被按下,%s\n", data)
}
}
package main
import (
"fmt"
"os"
"strconv"
"time"
"github.com/mattn/go-gtk/gdk"
"github.com/mattn/go-gtk/gdkpixbuf"
"github.com/mattn/go-gtk/gtk"
)
func main() {
gtk.Init(&os.Args)
//加载glade文件
builder := gtk.NewBuilder()
builder.AddFromFile("C:/Users/dawnl/Desktop/GO/src/GTK/test1.glade")
//获取glade的控件
win := gtk.WindowFromObject(builder.GetObject("window1"))
//win.Show() //显示控件,如果是通过glade添加的控件,show()即可
//如果是通过代码布局添加的控件,需要逐个show或showall
b1 := gtk.ButtonFromObject(builder.GetObject("button1"))
b2 := gtk.ButtonFromObject(builder.GetObject("button2"))
label := gtk.LabelFromObject(builder.GetObject("label1"))
label.SetText("你大爷")
label.ModifyFontSize(30)
label.ModifyFG(gtk.STATE_NORMAL, gdk.NewColor("BLACK"))
image := gtk.ImageFromObject(builder.GetObject("image1"))
var x, y int
image.GetSizeRequest(&x, &y)
pixbuf, _ := gdkpixbuf.NewPixbufFromFileAtScale("C:/Users/dawnl/Desktop/web.png", x-10, y-10, false)
image.SetFromPixbuf(pixbuf)
pixbuf.Unref()
//获取进度条控件
pg := gtk.ProgressBarFromObject(builder.GetObject("progressbar1"))
ch := make(chan int)
go func() {
t := 1.0
for i := 1; i <= 1000; i++ {
pg.SetFraction(t)
pg.SetText(strconv.Itoa(100-i/10) + "%")
time.Sleep(time.Millisecond * 10)
t -= 0.001
if i == 1000 {
ch <- 1
fmt.Println("结束")
}
}
}()
go func() {
fmt.Println("阻塞")
<-ch
//win.Destroy()
}()
win.Show()
//信号处理
b1.Clicked(
func() {
fmt.Println("按下了button1")
})
b2.Clicked(
func() {
fmt.Println("按下了button2")
})
win.Connect("destroy", func() {
gtk.MainQuit()
})
gtk.Main()
}
//键鼠事件
package main
import "fmt"
import "os"
import "github.com/mattn/go-gtk/gtk"
import "github.com/mattn/go-gtk/gdk"
import "github.com/mattn/go-gtk/glib"
import "unsafe"
func main() {
gtk.Init(&os.Args)
win := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
win.SetSizeRequest(420, 380)
//gdk.BUTTON_PRESS_MASK 鼠标按下,触发信号,button-press-event
//gdk.BUTTON1_MOTION_MASK 鼠标移动,按下任何键移动都可以 触发信号 motion-notify-event
win.SetEvents(int(gdk.BUTTON_PRESS_MASK | gdk.BUTTON1_MOTION_MASK)) //设定捕获属性
// 鼠标按下时出发,"button-press-event"
win.Connect("button-press-event", func(ctx *glib.CallbackContext) {
//fmt.Println("鼠标按下")
arg := ctx.Args(0)
event := *(**gdk.EventButton)(unsafe.Pointer(&arg))
//fmt.Println(event.Button)//左键1,2中间键,3为右键
flag := event.Button
if flag == 1 {
fmt.Print("左键\t")
} else if flag == 2 {
fmt.Print("中间键\t")
} else {
fmt.Print("右键\t")
}
if event.Type == int(gdk.BUTTON_PRESS) {
fmt.Print("单击\t")
} else if event.Type == int(gdk.BUTTON2_PRESS) {
fmt.Print("双击\t")
}
fmt.Printf("相对于窗口 :( %v,%v )\t", event.X, event.Y)
fmt.Printf("相对于屏幕 :( %v,%v )\n", event.XRoot, event.YRoot)
})
//改变窗口大小时触发
win.Connect("configure-event", func() {
var w, h int
win.GetSize(&w, &h)
fmt.Printf("w=%d h=%d\n", w, h)
//第一次窗口从无到有
//第二次改变窗口
})
win.Connect("key-press-event", func(ctx *glib.CallbackContext) {
//获取键盘按下属性结构体变量,系统内部变量,不是用户传的变量
arg := ctx.Args(0)
event := *(**gdk.EventKey)(unsafe.Pointer(&arg))
//获取到的实际是字母的ascii码
key := event.Keyval
fmt.Printf("key===%v\n", key)
if key == gdk.KEY_a {
fmt.Println("aaaaaaa")
}
})
win.Connect("motion-notify-event", func(ctx *glib.CallbackContext) {
//获取鼠标按下属性结构体变量,系统内部变量,不是用户传的变量
arg := ctx.Args(0)
event := *(**gdk.EventButton)(unsafe.Pointer(&arg))
fmt.Printf("======相对于窗口 :( %v,%v ) ", event.X, event.Y)
fmt.Printf("======相对于屏幕 :( %v,%v )\n", event.XRoot, event.YRoot)
})
win.Show()
win.Connect("destroy", func() {
gtk.MainQuit()
})
gtk.Main()
}
//绘图事件
package main
//import "fmt"
import "os"
import "github.com/mattn/go-gtk/gtk"
import "github.com/mattn/go-gtk/gdk"
import "github.com/mattn/go-gtk/gdkpixbuf"
func main() {
gtk.Init(&os.Args)
builder := gtk.NewBuilder()
builder.AddFromFile("./paint.glade")
win := gtk.WindowFromObject(builder.GetObject("window1"))
win.Connect("destroy", func() {
gtk.MainQuit()
})
var w, h int
win.Connect("configure-event", func() {
win.GetSize(&w, &h)
//fmt.Println("w:", w, " h:", h)
//刷图,整个窗口区域刷图
win.QueueDraw() //触发下边的expose-event信号
})
//画背景图,允许窗口绘图
win.SetAppPaintable(true)
x := 0
win.Connect("expose-event", func() {
//设置画家指定绘图区域
painter := win.GetWindow().GetDrawable()
gc := gdk.NewGC(painter)
//创建图片资源
bg, _ := gdkpixbuf.NewPixbufFromFileAtScale("C:/Users/dawnl/Desktop/素材女.jpg", w, h, false)
face, _ := gdkpixbuf.NewPixbufFromFileAtScale("C:/Users/dawnl/Desktop/滑稽.jpg", 85, 80, false)
painter.DrawPixbuf(gc, bg, 0, 0, 0, 0, -1, -1, gdk.RGB_DITHER_NONE, 0, 0)
painter.DrawPixbuf(gc, face, 0, 0, x, 150, -1, -1, gdk.RGB_DITHER_NONE, 0, 0)
bg.Unref() //释放图片资源
face.Unref()
})
//获取按钮
butt := gtk.ButtonFromObject(builder.GetObject("button1"))
butt.Clicked(func() {
x += 50
if x >= w {
x = 0
}
win.QueueDraw() //触发下边的expose-event信号
})
win.Show()
gtk.Main()
}
//无边框窗口移动
package main
import "os"
import "github.com/mattn/go-gtk/gtk"
import "unsafe"
import "github.com/mattn/go-gtk/gdk"
import "github.com/mattn/go-gtk/glib"
func main() {
gtk.Init(&os.Args)
win := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
win.SetSizeRequest(480, 320)
win.SetDecorated(false) //去边框
x, y := 0, 0
win.SetEvents(int(gdk.BUTTON_PRESS_MASK | gdk.BUTTON1_MOTION_MASK)) //设定捕获属性
// 鼠标按下时出发,"button-press-event"
win.Connect("button-press-event", func(ctx *glib.CallbackContext) {
//fmt.Println("鼠标按下")
arg := ctx.Args(0)
event := *(**gdk.EventButton)(unsafe.Pointer(&arg))
x, y = int(event.X), int(event.Y)
if event.Button == 3 { //3是鼠标右键
gtk.MainQuit()
}
})
win.Connect("motion-notify-event", func(ctx *glib.CallbackContext) {
//获取鼠标按下属性结构体变量,系统内部变量,不是用户传的变量
arg := ctx.Args(0)
event := *(**gdk.EventButton)(unsafe.Pointer(&arg))
win.Move(int(event.XRoot)-x, int(event.YRoot)-y)
})
win.Show()
gtk.Main()
}
随便写写
GUI:图形界面,是为了方便非专业用户使用
字符界面,敲命令
go语言gui编程:使用GTK(框架)
需要配置gopath
控件,部件,构件
控件:属性、方法
按钮:文本信息(属性),动作(方法)
控件分类:
窗口 放容器
容器 放控件
信号:中断
步骤:
创建窗口
设置窗口属性
创建布局
布局添加到窗口
创建控件(按钮)
设置控件属性
控件添加到布局 设置坐标(很抽象)
处理信号
显示所有控件
glade 常规,公共同步设置大小
glade 流程
1 加载glade文件
2 获取控件
3 信号处理
4 显示控件
绘图事件可能什么都不用做就会被触发
任何视觉上变化都会自动触发绘图事件
哪部分变化,哪部分刷新
可以认为刷新
画图,找个画家,画在绘图区域
w,h, -1,-1 按原先的来
(本笔记内容整理自网络资源,侵删)