原文 QML Engine Internals, Part 4: Custom Parsers

———————————————————————————————————————————

上一篇 绑定类型

简要回顾

 
图1 QML例子

Q_PROPERTYs无处不在?

让我们稍微扩展一下这个例子,当鼠标点击时,将矩形变红:

 
图2 扩展例子

自定义解析器

仔细阅读QQuickPropertyChanges类的头文件,我们找到了一点破解颜色属性秘密的线索:在文件末尾还有另一个类:QQuickPropertyChangesParser,它继承于QQmlCustomParser。

想要了解自定义解析器到底是如何工作的,我们得先回顾一下QML文件的加载,在第一篇博文中就已经讲解了,QML文件的加载分为两个阶段:

1.编译阶段

QML文件会被解析和编译一次,最后会创建一个包含指令列表的QQmlCompiledData对象。除指令列表外,它还包含了一些补充这些指令的二进制数据。阅读之前的博文可以看到这些指令是什么样子的。

2.生成阶段

当QML文件被实例化后,QML引擎就会在QQmlCompiledData对象中查找指令,并在虚拟机中执行它们。

自定义解析器在编译和生成阶段都会被调用:

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
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

深入解析QML引擎, 第4部分: 自定义解析器的更多相关文章

  1. 深入解析QML引擎, 第3部分: 绑定类型

    原文 QML Engine Internals, Part 3: Binding Types 译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/Q ...

  2. 深入解析QML引擎, 第2部分: 绑定(Bindings)

    原文  QML Engine Internals, Part 2: Bindings 译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/QML爱好 ...

  3. 深入解析QML引擎, 第1部分:QML文件加载

    译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/QML爱好者和工作者也能更好的学习和理解QML引擎,故将这个系列的4篇文章翻译过来.翻译并不是完 ...

  4. 深度解析qml引擎---(2)绑定(binding)

    强烈的希望是人生中比任何欢乐更大的兴奋剂.--尼采 上一篇文章讲了QML引擎加载qml文件的过程,大体过程是,解析qml文件,然后为文件中的每个元素创建对应的c++对象.例如,qml文件中如果使用了T ...

  5. 深度解析qml引擎---(1)Qml文件加载

                                                                        "美的事物是永恒的喜悦" --- 济慈    ...

  6. AutoMapper之自定义解析

    自定义解析 4.自定义解析 AutoMapper可以通过名称匹配等规则进行对象的映射,但是在实际的项目中,只是这样是远远不够的,比说我们需要名称不同的字段进行映射,或者需要再加一些逻辑处理.AutoM ...

  7. QML引擎的演进,第一部分

    原文链接:Lars Knoll – Evolution of the QML engine, part 1 QML作为一项技术对于Qt的成功变得越来越重要.它允许创建流畅的动画界面,与现今的市场预期相 ...

  8. (转)浅谈dedecms模板引擎工作原理及自定义标签

    理解织梦模板引擎有什么意义?一方面可以更好地自定义标签.更多在于了解织梦系统,理解模板引擎是理解织梦工作原理的第一步.理解织梦会使我们写php代码时更顺手,同时能学习一些php代码的组织方式. 这似乎 ...

  9. 浅谈dedecms模板引擎工作原理及其自定义标签

    浅谈dedecms模板引擎工作原理: 理解织梦模板引擎有什么意思? 可以更好地自定义标签.更多在于了解织梦系统,理解模板引擎是理解织梦工作原理的第一步. 理解织梦会使我们写PHP代码是更顺手,同时能学 ...

随机推荐

  1. ubuntu使用----高效快捷键

    桌面快捷键 : ALT + F1: 聚焦到桌面左侧任务导航栏,可按上下键导航. ALT + F2: 运行命令 ALT + F4: 关闭窗口 ALT + TAB: 切换程序窗口 ALT + 空格: 打开 ...

  2. freemark生成静态网页乱码问题

    输出流问题:修改Writer如下: OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(dir), &quo ...

  3. Unity 4.7 导出工程在XCode10.1上编译报错

    Unity 4.7 导出工程在XCode 10.1上编译报错,而在XCode 9.3上是可以正常编译运行的.原因是Unity4.7所依赖的头文件和库文件在XCode10上没有了,解决办法如下,把XCo ...

  4. Java并发编程(六)原子性与易变性

    原子性 原子是最小单元.不可再分的意思.原子性是指某个操作在获取CPU时间时,要么就给它足够时间,让这个操作执行完,要么就不执行这个操作,执行时不能出现上下文切换(把CPU时间从一个线程分配到另一个线 ...

  5. 【js】javaScript 执行机制

    javascript 是一门单线程语言(按照语句一行一行的执行) let a = '1'; console.log(a); let b = '2'; console.log(b); 这样子正常执行是没 ...

  6. CentOS7.6离线安装JDK1.8

    卸载CentOS自带的openJDK: 查看openJDK命令:rpm -qa|grep java 结果: java-1.8.0-openjdk-headless-1.8.0.181-7.b13.el ...

  7. PE 学习之路 —— 区块表

    1. 前述 在 NT 头结束后,紧接着就是区块表,区块表包含每个块在映象中的信息,分别指向不同的区块实体. 2. 区块表 区块表是一个 IMAGE_SECTION_HEADER 结构数组,这个结构包含 ...

  8. 07.centos7构建 IntelliJ IDEA(简称IDEA)开发环境

    一.安装IDEA 进入官网下载linux版的社区便,IDEA分为社区版和旗舰版,社区版免费,并且基本满足spark开发需求. 解压安装 目录为/opt/idea 注意:centos命令行界面下是无法安 ...

  9. zookeeper无法启动"Unable to load database on disk

    QuorumPeerMain,ResourceManager都没有起来 resourcemanager.log如下 2018-09-28 23:17:02,787 FATAL org.apache.h ...

  10. Python学习 :反射 & 单例模式

    反射 什么是反射? - 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省) 面向对象中的反射 - 通过字符串的形式来操作(获取.检查.增加.删除)对象中的成员 - python中的 ...