模块化开发之二:标识模块
模块化开发之二:标识模块
标识模块是那些已被安装,并能被QML引擎通过URI(统一资源定位)来识别的模块。其中URI是包含点分隔符的字符串,它是由模块所在的qmldir文件指定的。这样,这些模块可以用统一的唯一标识符被导入,而不论这些模块在本地文件系统的任何位置。
当导入一个标识模块时,会用到一个未被引用的标识,并必须带一个版本号。
import QtQuick 2.0
import com.nokia.qml.mymodule 1.0
标识模型必须安装到导入路径,这样才能够被QML引擎发现。
本地安装的标识模块
QML和/或C++ 文件所在的文件夹可以作为标识模块,但前提是该文伯夹必须包含描述模块元数据的qmldir文件,并且(其路径)要被安装到QML导入路径中。如此一来,本地文件系统中的任何QML文件都可以通过引用模块URI的import声明,来导入这个路径作为模块,以使得文件能够使用模块中定义的QML对象类型和JavaScript脚本资源。
模型的qmldir文件必须位于导入路径下的一个文件夹中,这个文件夹路径反映为带有点分隔符的URI字符串,其中每个点号(“.”)表示路径树中的子级文件夹。比如,模块com.mycompany.mymodule 的qmldir必须位于某导入路径下的com/mycompany/mymodule/qmldir
可以在模块的子文件夹下存储不同版本的模块。比如,模块的2.1版本可以被放在com/mycompany/mymodule.2/qmldir 或 com/mycompany/mymodule.2.1/qmldir。引擎会根据匹配情况自动加载模块。
又或者,不同版本的类可以被定义在一个qmldir文件中,但这可能会使得更新这个模块变得更复杂(因为在部分更新的过程中必须会引发qmldir的合并)。
举个粟子
假定有以下项目文件结构的项目。在顶层目录myapp,其子目录mycomponents下有一组常用控件,而主应用代码在子目录main下,如下:
myapp
|- mycomponents
|- CheckBox.qml
|- DialogBox.qml
|- Slider.qml
|- main
|- application.qml
要使mycomponents路径做为标识模块,路径下必须有一个定义模块标识的qmldir文件,且文件中需要描述模块的对象类型。比如,要使模块中的CheckBox, DialogBox 和 Slider类型的1.0版本可用,qmldir文件必须包括以下内容:
module myapp.mycomponents
CheckBox 1.0 CheckBox.qml
DialogBox 1.0 DialogBox.qml
Slider 1.0 Slider.qml
另外,导入路径里的qmldir文件的位置必须与模块的点标识字符串相匹配。所以, 如果说顶层的myapp文件夹位于 C:\qml\projects,并且模块标识为"myapp.mycomponents",那么:
- 路径 C:\qml\projects 应该被添加到导入路径
- qmldir应该位于 C:\qml\projects\myapp\mycomponents\qmldir
请仔细阅读和理解以上这一段。实际操作中,经常有加载组件失败的情况,原因就在于导入路径没写对。一旦完成这些,位于本地文件系统的任何地方的QML文件都可以通过引用URI来导入恰当版本的模块:
import myapp.mycomponents 1.0
DialogBox {
CheckBox {
// ...
}
Slider {
// ...
}
}
远程安装的标识模块
标识模块也可以作为网络资源来访问。在前面的例子中,如果路径 C:\qml\projects 部署在 http://www.some-server.com/qml/projects 且URL被添加到QML的导入路径,则模块可以用完全相同的方式被导入。
注意,要通过网络导入模块时,只能访问模块的QML和JavaScript 资源,而不能访问模块中定义的任何C++ 插件类型。
标识模块的语义
QML引擎为标识模块提供三条保证:
- 其它模块不能修改或覆盖模块命名空间下的类型
- 其它模块不能在模块的命名空间下注册新类型
- 客户端对要使用的类型名的解析,取决于特定类型定义时指定的版本号和模块导入顺序
这确保调用模块的客户端,能够确定模块中的类型以模块作者标识声明的那样来使用。
标识模块有以下几个限制: - 标识模块必须安装到QML 导入路径
- 按照模块标识指令来指定的模块标识符必须匹配模块的安装路径(相对于QML 导入路径,路径分隔符由“.”换为“/”)
- 模块必须将其类型注册到模块标识的命名空间
- 模块不能注册其类型到任何其它模块空间
- 客户端在导入模块时必须指定版本
比如,如果一个标识模块安装到了 $QML2_IMPORT_PATH/ExampleModule,模块标识指令必须是:
module ExampleModule
如果模块被装到$QML2_IMPORT_PATH/com/example/CustomUi,那模块标识指令必须是:
module com.example.CustomUi
客户端将能够用以下导入声明来导入以上模型(假定模块将类型以版本号1.0注册到其命名空间):
import com.example.CustomUi 1.0