Go-Qt5開發之信號模擬(40)

Go-Qt5開發之信號模擬

前言

  • 在這系列案例中,對自定義信號的介紹是非常少的,在Qt中沒有自定義信號總感覺少了點什麼。
  • 之後的幾個信號案例,都是對信號章節的補充。
  • 於是去翻qt綁定(therecipe/qt )的案例,案例使用的是tags標籤機制,但發現案例不適用,當然可能也是我不會用。
  • 再接着到處找資料,網上對此介紹真的是非常的少。
  • 再之後,不斷的去翻看源碼來找答案,在最近終於做出了,初始方案。
  • 本方案,只是自己的理解,不一定對,僅供參考。

案例介紹

  • 本案例是根基源碼,進行的信號機制模擬;
  • 使用的是映射機制;

demo1.go

package main

import (
	"fmt"
	"reflect"
)

/*
映射以及函數調用
*/

func prints(f func()) {
	// 函數執行
	f()
}

func main() {
	/*
		// 解析
		// 得到反射對象
		fv := reflect.ValueOf(prints)

		// 創建一個長度爲1的控列表
		params := make([]reflect.Value, 1)

		// 要傳遞的參數;此處傳遞一個匿名函數
		f := func() {
			fmt.Println("********")
		}

		// 參數設置
		params[0] = reflect.ValueOf(f)
		// 要調用函數
		fv.Call(params)


	*/

	// 合併調用
	reflect.ValueOf(prints).Call([]reflect.Value{reflect.ValueOf(func() {
		fmt.Println("********")
	})})
}

demo2.go

package main

import (
	"fmt"
	"reflect"
	"runtime"
	"strings"
)

/*
模擬qt信號 信號鏈接
*/


// 以Connect開頭
func ConnectGoSignal(f func(clicked bool)) {
	// 函數執行
	func(checked bool) {
		//fmt.Println(checked)
		f(checked)
	}(true)
}

// 信號解析
func parse(f, a interface{}) {
	// 解析
	// 映射函數f,獲得對象
	ValueObj := reflect.ValueOf(f)
	// 獲取函數指針
	ValuePointer := ValueObj.Pointer()
	// 獲取函數名
	FuncForPC := runtime.FuncForPC(ValuePointer).Name()
	// 函數名切割
	Split := strings.Split(FuncForPC, ".Connect")
	// 獲取信號名
	Split1 := Split[1]
	// qt 信號:FuncForPC github.com/therecipe/qt/widgets.(*QAbstractButton).ConnectClicked-fm
	// 此處處理後綴
	fn := strings.TrimSuffix(Split1, "-fm")
	// 首字母小寫處理
	// 最終結果: test
	ToLower := strings.ToLower(fn[:1]) + fn[1:]
	fmt.Println("ValueObj", ValueObj)
	fmt.Println("ValuePointer", ValuePointer)
	fmt.Println("FuncForPC", FuncForPC)
	fmt.Println("Split", Split)
	fmt.Println("Split1", Split1)
	fmt.Println("fn", fn)
	fmt.Println("ToLower", ToLower)
	// 進行信號註冊
	// 此處模擬就不註冊了
	// t Qt__ConnectionType
	// qt.RegisterConnectionType(ValuePointer, ToLower, int64(t))

	// 映射函數a,獲取a對象
	ValueObjA := reflect.ValueOf(a)
	// 創建一個列表,存儲a
	ValueA := []reflect.Value{ValueObjA}
	fmt.Println("ValueOfA", ValueObjA)
	fmt.Println(reflect.TypeOf(ValueA), ValueA)
	// 調用函數,傳遞參數
	ValueObj.Call(ValueA)
}

func main() {
	// 傳遞的匿名函數
	a := func(checked bool) {
		fmt.Println("recv****************************")
	}
	// 參數模擬
	// 重新賦值
	f := ConnectGoSignal

	// 信號解析
	parse(f, a)

	// ConnectSignal 函數原型
	fn := strings.TrimSuffix(strings.Split(runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name(), ".Connect")[1], "-fm")
	// 進行信號註冊
	// 此處模擬就不註冊了
	// t Qt__ConnectionType
	// qt.RegisterConnectionType(f.Pointer(), strings.ToLower(fn[:1])+fn[1:], int64(t))
	fmt.Println(fn)
	reflect.ValueOf(f).Call([]reflect.Value{reflect.ValueOf(a)})
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章