深刻解析QML引擎, 第4部分: 自定義解析器

原文 QML Engine Internals, Part 4: Custom Parsershtml

———————————————————————————————————————————ui

上一篇 綁定類型翻譯

簡要回顧

 
圖1 QML例子

Q_PROPERTYs無處不在?

讓咱們稍微擴展一下這個例子,當鼠標點擊時,將矩形變紅:調試

 
圖2 擴展例子

自定義解析器

仔細閱讀QQuickPropertyChanges類的頭文件,咱們找到了一點破解顏色屬性祕密的線索:在文件末尾還有另外一個類:QQuickPropertyChangesParser,它繼承於QQmlCustomParser。code

想要了解自定義解析器究竟是如何工做的,咱們得先回顧一下QML文件的加載,在第一篇博文中就已經講解了,QML文件的加載分爲兩個階段:orm

1.編譯階段

QML文件會被解析和編譯一次,最後會建立一個包含指令列表的QQmlCompiledData對象。除指令列表外,它還包含了一些補充這些指令的二進制數據。閱讀以前的博文能夠看到這些指令是什麼樣子的。htm

2.生成階段

當QML文件被實例化後,QML引擎就會在QQmlCompiledData對象中查找指令,並在虛擬機中執行它們。對象

自定義解析器在編譯和生成階段都會被調用:blog

1.在編譯階段,QQmlCustomParser::compile()將被調用

下面的一點調試代碼證明了顏色屬性是被傳遞到了自定義解析器中:繼承

 
圖3  證明屬性的調試代碼

輸出:

 
圖4 調試代碼輸出結果

就PropertyChanges的自定義解析器而言,它只是簡單地將參數按原樣序列化存入QByteArray。

2.在生成階段,QQuickPropertyChangesParser::setCustomData()被調用

在咱們這個例子中,PropertyChanges的自定義解析器只是簡單地把數據傳遞給QQuickPropertyChanges對象。稍後,由QQuickPropertyChangesPrivate::decode()對這些數據作一些處理:對數據進行反序列化。而後建立一個ExpressionChange對象列表。當屬性改變時,這些ExpressionChange就會被執行。

由於QQmlCustomParser是私有的API,因此編寫本身的自定義解析器並非那麼簡單。

總結

爲了支持QML元素中的任意屬性,除了使用正常的Q_PROPERTYs,還須要使用自定義解析器。這些自定義解析器得到全部未知屬性的列表後,能夠對這些屬性作任何處理。QML文件的加載過程當中,存在編譯和生成兩個階段。在編譯階段,自定義解析器建立一個存儲二進制數據QByteArray,它存儲全部在生成階段須要的信息。在生成階段,這個QByteArray被傳遞給了自定義解析器,這時自定義解析器才真正意義上地使用這些數據。

討論

PropertyChanges元素具備自定義分析器是至關方便的,僅列出color: "red"就至關不錯了。更妙的是,你能夠很輕鬆地列出多個屬性:

 
圖5 多屬性例子

與之造成對比的是,使用稍微醜陋一點語法的PropertyAction:

 
圖6 PropertyAction

這裏存在一個不一致的地方:在一種狀況下,可以使用優美的語法,在其餘狀況下,則不能。在我看來是至關混亂的,特別是在你不瞭解自定義解析器的狀況下。

另外一個例子是ListElement元素,它一樣具備一個自定義解析器。由於它的屬性是由自定義解析器解析的,它們表現得不太像正常屬性。就我我的而言,我偶然發現了它們的奇怪行爲,好比QTBUG-16289

最後一個使用自定義解析器的例子是Connections元素,當鏈接到一個從C++裏導出的對象的信號時,這是很是有用的:

 
圖7 Connections

你是怎麼看待自定義解析器存在的意義的?

至此,4篇文章所有翻譯結束了,若是有什麼疑問或者對QML應用和研究感興趣的朋友,歡迎加入咱們進行討論(QQ羣:280689979)。如需轉載,無須咱們受權,但須要註明原文連接(該文的連接),及原做者,謝謝!

上一篇 綁定類型

做者:猿基地 連接:https://www.jianshu.com/p/070f1d94071b 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
相關文章
相關標籤/搜索