go-gtk3开发之定时器控件
案例说明
创建一个定时器与按钮进行绑定,点击按钮后开始计数,点击停止后停止计数。
demo1.go
package main
import (
"fmt"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
"log"
"os"
"reflect"
"strconv"
)
/*
func TimeoutAdd(interval uint, f interface{}, datas ...interface{}) (id int)
功能:创建定时器
参数:
interval:设置的时间间隔,以毫秒为单位(1000即为1秒 )
f:回调函数的名字,回调函数的返回类型为bool,当回调函数返回值为false时,定时器执行一次后便会停止工作,不再循环执行。所以,要想定时器连续工作,循环执行所指定的回调函数,应该返回true。
datas:给回调函数传的参数
返回值:定时器id号
func TimeoutRemove(id int)
功能:移除定时器
参数:定时器id号
*/
func main() {
const appId = "com.nayoso.example"
app, _ := gtk.ApplicationNew(appId, glib.APPLICATION_FLAGS_NONE)
_, err := app.Connect("activate", func() {
createWindow(app)
})
if err != nil {
log.Fatal(err)
}
app.Run(os.Args)
}
func createWindow(application *gtk.Application) {
// 从文件中创建Builder
builder, err := gtk.BuilderNewFromFile("15_定时器/builder.ui")
if err != nil {
log.Fatal(err)
}
// 获取window窗口
winObj, _ := builder.GetObject("window1")
window := winObj.(*gtk.Window)
application.AddWindow(window)
// window 窗口设置
window.SetSizeRequest(300, 240) //设置窗口大小
window.SetTitle("hello go") //设置标题
window.SetResizable(false) //设置不可伸缩
window.SetPosition(gtk.WIN_POS_CENTER) //设置居中显示
err = window.SetIconFromFile("images/app.ico") //设置icon
if err != nil {
log.Fatal(err)
}
labelObj, _ := builder.GetObject("label")
buttonStartObj, _ := builder.GetObject("buttonStart")
buttonStopObj, _ := builder.GetObject("buttonStop")
label := labelObj.(*gtk.Label)
buttonStart := buttonStartObj.(*gtk.Button)
buttonStop := buttonStopObj.(*gtk.Button)
//label.ModifyFontSize(50) //设置label字体大小
buttonStop.SetSensitive(false) //停止按钮不能按
//var id uint //定时器id
var flag bool = true
var num int = 1 //累加标记
//信号处理
//启动按钮
_, _ = buttonStart.Connect("clicked", func() {
//启动定时器, 500毫秒为时间间隔,回调函数为匿名函数
//定时器id
id, _ := glib.TimeoutAdd(500, func() bool {
num++
label.SetText(strconv.Itoa(num)) //给标签设置内容
if flag {
return true //只要定时器没有停止,时间到自动调用回调函数
}else {
return false
}
})
fmt.Println("id", reflect.TypeOf(id), id)
buttonStart.SetSensitive(false) //启动按钮变灰,不能按
buttonStop.SetSensitive(true) //定时器启动后,停止按钮可以按
})
//停止按钮
_, _ = buttonStop.Connect("clicked", func() {
//停止定时器
//glib.TimeoutRemove(id)
flag = false
buttonStart.SetSensitive(true)
buttonStop.SetSensitive(false)
})
// 显示所有界面
window.ShowAll()
}
/*
信号标识 触发条件
“clicked” 按下按钮时触发
“pressed” 按下按钮时触发
“released” 释放按钮时触发
*/
builder.ui
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.24"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<child>
<object class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<child>
<object class="GtkButton" id="buttonStart">
<property name="label" translatable="yes">buttonStart</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttonStop">
<property name="label" translatable="yes">buttonStop</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">0</property>
</object>
<packing>
<property name="right_attach">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
demo2.go
package main
import (
"fmt"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
"log"
"os"
"reflect"
"strconv"
)
/*
func TimeoutAdd(interval uint, f interface{}, datas ...interface{}) (id int)
功能:创建定时器
参数:
interval:设置的时间间隔,以毫秒为单位(1000即为1秒 )
f:回调函数的名字,回调函数的返回类型为bool,当回调函数返回值为false时,定时器执行一次后便会停止工作,不再循环执行。所以,要想定时器连续工作,循环执行所指定的回调函数,应该返回true。
datas:给回调函数传的参数
返回值:定时器id号
func TimeoutRemove(id int)
功能:移除定时器
参数:定时器id号
*/
func main() {
const appId = "com.nayoso.example"
app, _ := gtk.ApplicationNew(appId, glib.APPLICATION_FLAGS_NONE)
_, err := app.Connect("activate", func() {
createWindow(app)
})
if err != nil {
log.Fatal(err)
}
app.Run(os.Args)
}
func createWindow(application *gtk.Application) {
// 从文件中创建Builder
builder, err := gtk.BuilderNewFromFile("15_定时器/builder.ui")
if err != nil {
log.Fatal(err)
}
// 获取window窗口
winObj, _ := builder.GetObject("window1")
window := winObj.(*gtk.Window)
application.AddWindow(window)
// window 窗口设置
window.SetSizeRequest(300, 240) //设置窗口大小
window.SetTitle("hello go") //设置标题
window.SetResizable(false) //设置不可伸缩
window.SetPosition(gtk.WIN_POS_CENTER) //设置居中显示
err = window.SetIconFromFile("images/app.ico") //设置icon
if err != nil {
log.Fatal(err)
}
labelObj, _ := builder.GetObject("label")
buttonStartObj, _ := builder.GetObject("buttonStart")
buttonStopObj, _ := builder.GetObject("buttonStop")
label := labelObj.(*gtk.Label)
buttonStart := buttonStartObj.(*gtk.Button)
buttonStop := buttonStopObj.(*gtk.Button)
//label.ModifyFontSize(50) //设置label字体大小
buttonStop.SetSensitive(false) //停止按钮不能按
var id glib.SourceHandle //定时器id
var num int = 1 //累加标记
//信号处理
//启动按钮
_, _ = buttonStart.Connect("clicked", func() {
//启动定时器, 500毫秒为时间间隔,回调函数为匿名函数
//定时器id
id, _ = glib.TimeoutAdd(500, func() bool {
num++
label.SetText(strconv.Itoa(num)) //给标签设置内容
return true //只要定时器没有停止,时间到自动调用回调函数
})
fmt.Println("id", reflect.TypeOf(id), id)
buttonStart.SetSensitive(false) //启动按钮变灰,不能按
buttonStop.SetSensitive(true) //定时器启动后,停止按钮可以按
})
//停止按钮
_, _ = buttonStop.Connect("clicked", func() {
//停止定时器
//glib.TimeoutRemove(id)
glib.SourceRemove(id)
buttonStart.SetSensitive(true)
buttonStop.SetSensitive(false)
})
// 显示所有界面
window.ShowAll()
}
/*
信号标识 触发条件
“clicked” 按下按钮时触发
“pressed” 按下按钮时触发
“released” 释放按钮时触发
*/
demo3.go
package main
import (
"fmt"
"log"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
)
var timeoutContinue = true
var tos glib.SourceHandle
// Create and initialize the window
func setupWindow(title string) *gtk.Window {
win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
if err != nil {
log.Fatal("Unable to create window:", err)
}
win.SetTitle(title)
win.Connect("destroy", func() {
gtk.MainQuit()
})
win.SetPosition(gtk.WIN_POS_CENTER)
width, height := 600, 300
win.SetDefaultSize(width, height)
box, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
btn, _ := gtk.ButtonNew()
btn.Connect("clicked", buttonClicked)
btn.SetLabel("Stop timeout")
box.Add(btn)
win.Add(box)
return win
}
func main() {
gtk.Init(nil)
win := setupWindow("Go Example Testreport")
win.ShowAll()
// Init timeout:
tos, _ = glib.TimeoutAdd(uint(1000), func() bool {
fmt.Println("timed out")
return timeoutContinue
})
gtk.Main()
}
func buttonClicked() {
var methode int
// Three methods to stop timeout:
// 1- Destroying
// 2- Removing
// 3- Returning false by called function
// Choose one of them:
methode = 3
switch methode {
case 1: // 1- Destroying
mcd := glib.MainContextDefault()
src := mcd.FindSourceById(tos)
src.Destroy()
fmt.Printf("Timeout stopped & IsDestroyed: %v\n", src.IsDestroyed())
case 2: // 2- Removing
glib.SourceRemove(tos)
fmt.Printf("Timeout stopped but still referenced\n")
case 3: // 3- Returning false by called function
timeoutContinue = !timeoutContinue
fmt.Printf("Timeout stopped but still in memory and referenced\n")
}
}