内容简介:我们已经介绍了qt的tags由反引号包裹,name在
我们已经介绍了qt的 signal 和 slot ,现在该讲讲它的struct tags系统了。qt拥有多种的struct tags,我们会去一一了解它们。
什么是struct tags?
struct tag
又叫做结构体标签,顾名思义,它就是用来给结构体字段做标记的。比如我们熟悉的JSON就使用了tags:
type User struct {
UserId int `json:"user_id" bson:"user_id"`
UserName string `json:"user_name" bson:"user_name"`
}
tags由反引号包裹,name在 :
之前,value在 :
之后由双引号包裹。
有了这些tags,我们的代码就可以很轻松的使用reflect来取得tags的name和name对应的值:
u := &User{UserId: 1, UserName: "tony"}
t := reflect.TypeOf(u)
field := t.Elem().Field(0)
fmt.Println(field.Tag.Get("json")) // "user_id"
fmt.Println(field.Tag.Get("bson")) // "user_id"
我们的qt正是依赖这一特性实现了Qt的moc系统,使用不同的tags除了可以实现signal和slot之外还能实现moc的多种功能,甚至是qt自己的一些扩展。
“->” 和 “<-”
在signal里我们已经介绍了auto,它具有很多的局限性,项目作者也表示auto应该尽量单独使用,不应该使用 auto(...)
的形式。而为了更方便的连接signal和slot,我们就需要用到 ->
和 <-
了。
先看个示例,这次我们从官方的例子里节选一段:
type Chart struct {
core.QObject
*charts.QChart
_ func() `constructor:"init"`
_ func() `slot:"handleTimeout,<-(this.m_timer.timeout)"`
}
对于槽handleTimeout,我们使用了 <-
,它和下面这句等价:
this.m_timer.ConnectTimeout(this.handleTimeout)
意思是将 this.m_timer
的Timeout信号和 this.handleTimeout
函数connect,当触发了 this.m_timer
的Timeout信号时这个函数也会被调用。
你也可以不指定信号名称,默认会和signal tag指定的信号名同名的函数进行connect:
_ func() `slot:"handleTimeout,<-(this.m_timer)"`
和
_ func() `slot:"handleTimeout,<-(this.m_timer.handleTimeout)"`
等价。
我们再来看一下 ->
的使用:
import "controller"
type dialogTemplate struct {
core.QObject
_ func() `constructor:"init"`
_ func(cident string) `signal:"show,<-(controller.Controller)"`
_ func(bool) `signal:"blur,->(controller.Controller)"`
}
可以看到,我们对信号Blur使用了 ->
,这个表达的含义与 <-
相反,它是将signal tag声明的信号或是slot tag声明的槽与 ->
之后的函数进行connect,当你触发这个信号或是调用这个槽时,括号内的函数也会被调用,等价于:
this.ConnectBlur(controller.Controller.blur)
或是(如上面所说,可以省略函数名)
this.ConnectBlur(controller.Controller)
“->”和“<-”的一些使用规则
上一段里我们已经提到可以在这两个tags里省略连接和被连接对象的函数名,这里还有几个规则:
-
括号里指定的可以是全局对象,包括导入的包里的可见对象,例如上个例子里的
controller.Controller。 -
this代指当前对象的实例(可以理解为c++的
this,python的self占位符,或者golang的receiver)。 -
括号里的内容还可以是
this.StructField,也就是对象里的字段 -
对于想连接继承的
QObject及其派生类或是其他类的signal/slot,目前只能使用this.BaseClass.method的形式(与auto类似),这一点作者表示会在以后改进。
“->”和“<-”以及“auto”
这三者都需要和signal/slot tag配合使用,他们都会自动connect信号和槽,但是它们也有许多不同。
-
首先我们日常使用应该尽量使用
singal:"signalName,auto"而不是auto(...),->或<-,如果只是为了少写Connect*,那么不应使用后三者,因为除非你有大量的Connect*需要编写,否则容易影响代码阅读,特别是对连接对象是当前类实例的成员函数时。 -
->和<-用于不同的对象之间进行交互,比起分散的Connect*调用,在struct tags里声明逻辑关系更易于维护。 -
->和<-用于连接已有的信号和槽,如果想复用基类或者成员变量的signal和slot,你就需要->或<-替代auto。 -
和QML交互时,也应该使用
->和<-连接来自QML的signals。
客观上这三者都能极大的简化我们对signal/slot的实现和使用,所以根据不同的场景需求,我们需要选用合适的tags来简化我们的开发。
下一篇文章我们将了解 constructor
这个tag,qt中的构造函数。
如果对本篇有什么疑问或者建议,欢迎在评论中提出。
祝玩得愉快!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Hacking Growth
Sean Ellis、Morgan Brown / Crown Business / 2017-4-25 / USD 29.00
The definitive playbook by the pioneers of Growth Hacking, one of the hottest business methodologies in Silicon Valley and beyond. It seems hard to believe today, but there was a time when Airbnb w......一起来看看 《Hacking Growth》 这本书的介绍吧!