Go-Qt5开发之QPushButton演变自定义信号(41)

Go-Qt5开发之QPushButton演变自定义信号

案例介绍

  • 本案例是从QPushButton信号进行逐渐演变成自定义信号;
  • 定本案例继承至core.QObject;
  • 最终定案:demo4.go
  • 本方案,只是本身的理解,不必定对,仅供参考。

demo1.go

package main

import "C"
import (
	"fmt"
	"github.com/therecipe/qt/core"
	"github.com/therecipe/qt/gui"
	"github.com/therecipe/qt/widgets"
	"os"
)

/*
直接使用butn.ConnectClicked信号
*/

func InitUi() *widgets.QMainWindow {
	// 建立窗口
	app := widgets.NewQMainWindow(nil, 0)

	// 设置窗口的标题
	app.SetWindowTitle("Qt 教程")

	// 设置窗口的位置和大小
	app.SetGeometry2(300, 300, 300, 220)

	// 设置窗口的图标,引用当前目录下的web.png图片
	app.SetWindowIcon(gui.NewQIcon5("images/app.ico"))

	//obj := core.NewQObject(nil)
	obj := core.QObject{}
	a := func(checked bool) {
		fmt.Println("recv")
	}

	butn := widgets.NewQPushButton2("按钮", app)
	butn.Move2(50, 50)

	f := butn.ConnectClicked
	obj.ConnectSignal(f, a, core.Qt__AutoConnection)

	return app
}

func main() {
	// 建立一个应用程序对象
	// sys.argv参数是一个列表,从命令行输入参数
	widgets.NewQApplication(len(os.Args), os.Args)

	// 初始化窗口
	app := InitUi()

	// 显示组件
	app.Show()

	// 确保应用程序干净的退出
	widgets.QApplication_Exec()
}

demo2.go

package main

import "C"
import (
	"fmt"
	"github.com/therecipe/qt/core"
	"github.com/therecipe/qt/gui"
	"github.com/therecipe/qt/widgets"
	"os"
)

/*
自定义信号,调用响应函数

调用比较直接, 无限接近直接调用
*/

type GoSignal struct {
	core.QObject
	arg interface{}
}

func (g *GoSignal) ConnectGoSignal(a func()) {
	func() {
		a()
	}()
}

func (g *GoSignal) Connect(a func()) {
	// 会直接执行
	g.ConnectSignal(g.ConnectGoSignal, a, core.Qt__AutoConnection)
}

func InitUi() *widgets.QMainWindow {
	// 建立窗口
	app := widgets.NewQMainWindow(nil, 0)

	// 设置窗口的标题
	app.SetWindowTitle("Qt 教程")

	// 设置窗口的位置和大小
	app.SetGeometry2(300, 300, 300, 220)

	// 设置窗口的图标,引用当前目录下的web.png图片
	app.SetWindowIcon(gui.NewQIcon5("images/app.ico"))

	//obj := core.NewQObject(nil)

	obj := GoSignal{}
	a := func() {
		fmt.Println("recv")
	}

	butn := widgets.NewQPushButton2("按钮", app)
	butn.Move2(50, 50)
	butn.ConnectClicked(func(checked bool) {
		obj.Connect(a)
	})


	return app
}

func main() {
	// 建立一个应用程序对象
	// sys.argv参数是一个列表,从命令行输入参数
	widgets.NewQApplication(len(os.Args), os.Args)

	// 初始化窗口
	app := InitUi()

	// 显示组件
	app.Show()

	// 确保应用程序干净的退出
	widgets.QApplication_Exec()
}

demo3.go

package main

import "C"
import (
	"errors"
	"fmt"
	"github.com/therecipe/qt"
	"github.com/therecipe/qt/core"
	"github.com/therecipe/qt/gui"
	"github.com/therecipe/qt/widgets"
	"os"
	"unsafe"
)

/*
ConnectGoSignal: 信号进行连接
Emit: 信号发送
信号不存在就不执行,并返回错误信息
*/

type GoSignal struct {
	core.QObject
	a interface{}
}

func (g *GoSignal) ConnectGoSignal(a interface{}) {
	if !qt.ExistsSignal(g.Pointer(), "goSignal") {
		g.a = a
		qt.ConnectSignal(g.Pointer(), "goSignal", unsafe.Pointer(&a))
	}
}

func (g *GoSignal) Emit() (err error) {
	err = nil
	if signal := qt.LendSignal(g.Pointer(), "goSignal"); signal != nil {
		func() {
			g.a.(func())()
		}()
	} else {
		err = errors.New("not ExistsSignal -> goSignal")
	}
	return err
}

func InitUi() *widgets.QMainWindow {
	// 建立窗口
	app := widgets.NewQMainWindow(nil, 0)

	// 设置窗口的标题
	app.SetWindowTitle("Qt 教程")

	// 设置窗口的位置和大小
	app.SetGeometry2(300, 300, 300, 220)

	// 设置窗口的图标,引用当前目录下的web.png图片
	app.SetWindowIcon(gui.NewQIcon5("images/app.ico"))

	obj := GoSignal{}
	a := func() {
		fmt.Println("demo3.go")
	}
	obj.ConnectGoSignal(a)

	butn := widgets.NewQPushButton2("按钮", app)
	butn.Move2(50, 50)
	butn.ConnectClicked(func(checked bool) {
		_ = obj.Emit()
	})

	return app
}

func main() {
	// 建立一个应用程序对象
	// sys.argv参数是一个列表,从命令行输入参数
	widgets.NewQApplication(len(os.Args), os.Args)

	// 初始化窗口
	app := InitUi()

	// 显示组件
	app.Show()

	// 确保应用程序干净的退出
	widgets.QApplication_Exec()
}

最终定案: demo4.go

package main

import "C"
import (
	"errors"
	"fmt"
	"github.com/therecipe/qt"
	"github.com/therecipe/qt/core"
	"github.com/therecipe/qt/gui"
	"github.com/therecipe/qt/widgets"
	"os"
	"unsafe"
)

/*
ConnectGoSignal: 信号进行连接
Emit: 无参数的自定义信号
Emit2:能够传递参数的自定义信号,对应响应函数也必须有参数接收
 */

type GoSignal struct {
	core.QObject
	a interface{}
}

func (g *GoSignal) ConnectGoSignal(a interface{}) {
	if !qt.ExistsSignal(g.Pointer(), "goSignal") {
		g.a = a
		qt.ConnectSignal(g.Pointer(), "goSignal", unsafe.Pointer(&a))
	}

	// 会直接执行
	//g.ConnectSignal(g.ConnectGoSignal, a, core.Qt__AutoConnection)
}

func (g *GoSignal) Emit() (err error) {
	err = nil
	if signal := qt.LendSignal(g.Pointer(), "goSignal"); signal != nil {
		func() {
			g.a.(func())()
		}()
	} else {
		err = errors.New("not ExistsSignal -> goSignal")
	}
	return err
}

func (g *GoSignal) Emit2(args interface{}) (err error) {
	err = nil
	if signal := qt.LendSignal(g.Pointer(), "goSignal"); signal != nil {
		func() {
			g.a.(func(args interface{}))(args)
		}()
	} else {
		err = errors.New("not ExistsSignal -> goSignal")
	}
	return err
}

func InitUi() *widgets.QMainWindow {
	// 建立窗口
	app := widgets.NewQMainWindow(nil, 0)

	// 设置窗口的标题
	app.SetWindowTitle("Qt 教程")

	// 设置窗口的位置和大小
	app.SetGeometry2(300, 300, 300, 220)

	// 设置窗口的图标,引用当前目录下的web.png图片
	app.SetWindowIcon(gui.NewQIcon5("images/app.ico"))

	obj := GoSignal{}
	a := func(args interface{}) {
		fmt.Println("args", args)
		fmt.Println("demo4.go")
	}
	obj.ConnectGoSignal(a)

	butn := widgets.NewQPushButton2("按钮", app)
	butn.Move2(50, 50)
	butn.ConnectClicked(func(checked bool) {
		_ = obj.Emit()
		//_ = obj.Emit2("测试传递参数")
	})

	return app
}

func main() {
	// 建立一个应用程序对象
	// sys.argv参数是一个列表,从命令行输入参数
	widgets.NewQApplication(len(os.Args), os.Args)

	// 初始化窗口
	app := InitUi()

	// 显示组件
	app.Show()

	// 确保应用程序干净的退出
	widgets.QApplication_Exec()
}