五张图了解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 按原先的来

(本笔记内容整理自网络资源,侵删)