【golang-GUI開發】struct tags系統(一)

來源:互聯網
上載者:User

我們已經介紹了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裡省略串連和被連線物件的函數名,這裡還有幾個規則:

  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中的建構函式。
如果對本篇有什麼疑問或者建議,歡迎在評論中提出。
祝玩得愉快!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.