go-gtk3开发之定时器控件(17)

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")
	}
}
发布了94 篇原创文章 · 获赞 52 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/weixin_43968923/article/details/105001675
今日推荐