使用Golang开发桌面GUI:gotk3

原地址:http://i.scwy.net/code/2020/070810-gui/
Golang之GUI: gotk3
Golang之GUI: gotk3 续一
Golang之GUI: gotk3 续二

最近花了点时间研究gotk3,网上资料很少,很费时。


考虑可能需要开发资源管理器/图片管理器,继续寻找golang的gui解决方案。

Github

这里有例程,我们都喜欢文档详细,例程多的东西。

依赖: sudo apt install libgtk-3-dev libcairo2-dev libglib2.0-dev

这里也讲了win环境下的安装。

网友的学习文章读一读

一 外带简单示例

第一次运行例程simple,好几分钟才出来,第二次运行就快多了。也不知道它内部在干啥。


package main


import (

"log"


"github.com/gotk3/gotk3/gtk"

)


func main() {

gtk.Init(nil) // 初始化GTK而不解析任何命令行参数。


//创建顶层窗口,当销毁时关联退出事件

win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) 。

if err != nil {

log.Fatal("Unable to create window:", err)

}

win.SetTitle("Simple Example")

win.Connect("destroy", func() {

gtk.MainQuit()

})


// 添加标签控件

l, err := gtk.LabelNew("Hello, gotk3!")

if err != nil {

log.Fatal("Unable to create label:", err)

}


// 控件加到窗口中

win.Add(l)


// 窗口大小

win.SetDefaultSize(800, 600)


// 递归显示此窗口中包含的所有小部件。

win.ShowAll()


// 开始主循环

gtk.Main()

}


使用Golang开发桌面GUI:gotk3_第1张图片

中文显示正常

二 库带小示例

看起来这个例子与库README中介绍的有点不同,看看:


import (

"log"

"os"


"github.com/gotk3/gotk3/glib"

"github.com/gotk3/gotk3/gtk"

)


func main() {

const appID = "org.gtk.example"

application, err := gtk.ApplicationNew(appID, glib.APPLICATION_FLAGS_NONE)

if err != nil {

log.Fatal("Could not create application.", err)

}

//关联激活事件

application.Connect("activate", func() { onActivate(application) })

os.Exit(application.Run(os.Args))

}


func onActivate(application *gtk.Application) {

appWindow, err := gtk.ApplicationWindowNew(application)

if err != nil {

log.Fatal("Could not create application window.", err)

}

//设置窗口相关属性

appWindow.SetTitle("简单应用窗口")

appWindow.SetDefaultSize(400, 400)

appWindow.Show()

}


代码还是容易理解。appID这个感觉有点象安卓App,给每个程序一个标识,一般使用公司域名。

或者以下代码也是一样。


package main


import (

"log"

"os"


"github.com/gotk3/gotk3/glib"

"github.com/gotk3/gotk3/gtk"

)


func main() {

const appID = "org.gtk.example"

application, err := gtk.ApplicationNew(appID, glib.APPLICATION_FLAGS_NONE)

if err != nil {

log.Fatal("Could not create application.", err)

}


application.Connect("activate", func() {

appWindow, err := gtk.ApplicationWindowNew(application)

if err != nil {

log.Fatal("Could not create application window.", err)

}

appWindow.SetTitle("Basic Application.")

appWindow.SetDefaultSize(400, 400)

appWindow.Show()

})

application.Run(os.Args)

}


三 按钮控件

添加按钮


package main


import (

"fmt"

"github.com/gotk3/gotk3/glib"

"github.com/gotk3/gotk3/gtk"

"log"

"os"

)


//这部分是相同的

func main() {

const appId = "com.nayoso.example"

app, err := gtk.ApplicationNew(appId, glib.APPLICATION_FLAGS_NONE)


if err != nil {

log.Fatal("Could not create application.", err)

}


app.Connect("activate", func() {

onActivate(app)

} )


app.Run(os.Args)

}


//

func onActivate(application *gtk.Application) {


appWindow, err := gtk.ApplicationWindowNew(application)

if err != nil {

log.Fatal("Could not create application window.", err)

}

appWindow.SetTitle("Basic Application.")

appWindow.SetDefaultSize(400, 400)


buttonBox, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 2) //以水平布局创建一个容器, 第二个参数是其中控件的像素间隔

if err != nil {

log.Fatal(err)

}

appWindow.Add(buttonBox) //将布局添加到window中


button, err := gtk.ButtonNewWithLabel("Hello World") //创建一个按钮

if err != nil {

log.Fatal(err)

}

buttonBox.Add(button) //将按钮添加到box容器中


button.Connect("clicked", func() { //让我们为按钮点击添加一个函数,每次点击都会在命令行输出Hello World

fmt.Println("Hello World")

appWindow.Destroy() //摧毁窗口

})


appWindow.ShowAll() //与Show()不同在于,它会输出Window中的子控件。你可以修改,查看不同的效果

}

四 布局

看看布局的例子:


package main


import (

"os"


"github.com/gotk3/gotk3/glib"

"github.com/gotk3/gotk3/gtk"

)


func main() {

const appId = "com.nayoso.example"


app, _ := gtk.ApplicationNew(appId, glib.APPLICATION_FLAGS_NONE)

app.Connect("activate", func() {

onActivate(app)

})

app.Run(os.Args)

}


func onActivate(application *gtk.Application) {

appWindow, _ := gtk.ApplicationWindowNew(application)

appWindow.SetTitle("Grid example")

//-- 以上,通常的代码输入完了,接下就是这个例子的重点


grid, _ := gtk.GridNew() //创建容器

appWindow.Add(grid) //将容器添加到window中


//现在再让我们创建一些按钮来展示grid的效果

button1, _ := gtk.ButtonNewWithLabel("Button 1")

button2, _ := gtk.ButtonNewWithLabel("Button 2")

button3, _ := gtk.ButtonNewWithLabel("Button 3")

button4, _ := gtk.ButtonNewWithLabel("Button 4")

//将buttons添加到grid中

grid.Attach(button1, 0, 0, 1, 1) //参数:左,上,宽,高

grid.Attach(button2, 1, 0, 1, 1)

grid.Attach(button3, 0, 1, 2, 1)

grid.Attach(button4, 0, 2, 1, 1)

//-- 注意一下,按钮的位置就像在一个坐标轴中,原点在左上,x轴向右,y轴向下


appWindow.ShowAll()

}


使用Golang开发桌面GUI:gotk3_第2张图片

五 界面编辑

据说,可以通过GtkBuilder使用XML构建UI。

我的Ubuntu上是啥时候装上的?(sudo apt-get install glade) 运行 glade 就弹出了。

使用Golang开发桌面GUI:gotk3_第3张图片


package main


import (

"log"

"os"


"github.com/gotk3/gotk3/glib"

"github.com/gotk3/gotk3/gtk"

)


func main() {

const appId = "com.nayoso.example"


app, _ := gtk.ApplicationNew(appId, glib.APPLICATION_FLAGS_NONE)

app.Connect("activate", func() {

onActivate(app)

})

app.Run(os.Args)

}


//-- 在开始我们还是使用我们熟悉的代码


func onActivate(application *gtk.Application) {

if builder, err := gtk.BuilderNewFromFile("builder.ui"); err != nil { //从文件中创建Builder

log.Fatal(err)

} else if winObj, err := builder.GetObject("window"); err != nil { //从文件中读取window对象,其实际上是Gobject

log.Fatal(err)

} else {

window := winObj.(*gtk.Window) //由于winObj是Gobject,所以我们使用类型断言得到Gtk.Window对象

application.AddWindow(window) //记得将window加入我们的application中


window.ShowAll()

}

}


主菜ui






True

Grid

10





True





True

Button 1





0

0









True

Button 2





1

0









True

Quit





0

1

2


















运行后就可以看到上图中设计的样子了。

看起来ui设计器有点“博大精深”,稍后再研究。先把示例代码研究一翻。特别是去发现是否依然存在不能输入中文的问题。

使用Golang开发桌面GUI:gotk3_第4张图片

看起来并没有异常。仿佛就是它。

找到一些资源

github上搜索gogtk3,会有一些示例

GTK3 Glade示例

示例

网络通信实例

你可能感兴趣的:(golang)