【golang-GUI开发】struct tags系统(一)

栏目: C++ · 发布时间: 5年前

内容简介:我们已经介绍了qt的tags由反引号包裹,name在

我们已经介绍了qt的 signalslot ,现在该讲讲它的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里省略连接和被连接对象的函数名,这里还有几个规则:

  1. 括号里指定的可以是全局对象,包括导入的包里的可见对象,例如上个例子里的 controller.Controller
  2. this代指当前对象的实例(可以理解为c++的 this ,python的 self 占位符,或者golang的 receiver )。
  3. 括号里的内容还可以是 this.StructField ,也就是对象里的字段
  4. 对于想连接继承的 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中的构造函数。

如果对本篇有什么疑问或者建议,欢迎在评论中提出。

祝玩得愉快!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

浪潮式发售

浪潮式发售

[美] 杰夫.沃克(Jeff Walker) / 李文远 / 广东人民出版社 / 2016-3-1 / 39.80元

10天时间,4种发售路径, 让你的产品一上架就被秒杀 投资失败的个体户,怎样让长期积压的库存,变成众人抢购的稀缺品,最终敲开财富之门? 只有一腔热血的大学毕业生,怎样将原本无人问津的网球课程,发售成价值45万美元的专业教程? 长期脱离社会的全职主妇,如何白手起家,创造出自己的第一款爆品,并挽救即将破碎的家庭? 改变上述人士命运的是同一件法宝——产品发售方程式。互......一起来看看 《浪潮式发售》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具