深刻解析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 来源:简书 简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。
相关文章
相关标签/搜索