QML——添加自定义模块

时间:2021-04-09 07:44:46

一、模块的定义

在使用QML时,我们常常看到类似这样的语句:

import QtQuick 2.0
import QtSensors 5.0

通过这些import语句,我们就能使用QML中的相关控件了。

其实这就是导入模块的意思,它包括3个部分:import关键字、模块名称、版本号。

模块是一种封装的方式,设计它的人可以单独更新模块内容,然后更新版本号,对使用模块的人没有影响。在项目中,不同窗口可以使用同一模块中的一些类型。

Qt中已经有很多封装好的模块,我们可以在安装目录里找到:

QML——添加自定义模块

更多介绍,可以参考官方文档:http://doc.qt.io/qt-5/qtqml-modules-topic.html

二、定义一个模块

模块是由一个名为 qmldir 的文件指定的,我们可以打开Qt中模块所在的文件夹看看,每个模块都对应一个qmldir文件:

QML——添加自定义模块

为了便于理解,我举一个非常简单的例子——

定义一个名为CustomControl(自定义控件)的模块,这个模块里面有一个CustomButton.qml(自定义按钮)文件,也就是一个自定义的名为CustomButton的QML类型。

文件目录结构如下:

QML——添加自定义模块

下面来分步说明:

1.CustomButton.qml

一个很普通的自定义按钮类型,代码可参考:按钮

2.qmldir

每个模块都有一个qmldir文件,在文件中设置模块的名称、指定自定义类型等。比如:

module CustomControl
CustomButton 1.0 ./controls/CustomButton.qml

module <ModuleIdentifier> module关键字,后接模块标识符,每个qmldir文件只能有一个标识符。

[singleton] <TypeName> <InitialVersion> <File> singleton用来声明一个单例类型,它是可省略的。TypeName是类型名称。InitialVersion用来指定版本号。File是QML类型对应文件所在的位置。

以本例来说,类型名是CustomButton,版本号为1.0,文件使用的是相对路径,表示controls文件夹下面的CustomButton.qml文件。

OK,通过以上两步,我们的模块就已经定义好了!

qmldir文件中更多复杂的定义可参考官方文档:点我!

三、使用自定义模块

我们在main.cpp中加载main.qml界面。

第一种方法,可以直接在main.qml中导入qmldir文件所在路径:

import "./CustomControl"

可以参考http://doc.qt.io/qt-5/qtqml-syntax-directoryimports.html中的讲解

另一种方法是使用QML导入路径,首先看一下main.cpp是如何加载QML文件的:

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

首先定义一个QML引擎engine,然后通过engine传入qml文件。

当导入一个模块时,QML engine将会搜索导入路径 import path 来匹配模块。

可以通过 QQmlEngine::importPathList() 来查看导入路径有哪些:

QQmlApplicationEngine engine;
for(QString path : engine.importPathList())
qDebug() << path;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));  

在我的电脑中,结果如下:

QML——添加自定义模块

比如,我们平时使用的Qt Quick中的一些控件就在C:/Qt/Qt5.8.0/5.8/msvc2015/qml中。

可以看到,我们需要使用的自定义模块并不在这几个路径中的任意一个中,所以需要如何添加路径呢?

方法一:

使用 QML2_IMPORT_PATH 环境变量来指定模块所在路径,注意QML后面有个2。

在windows系统中,计算机 - 系统属性 - 高级系统属性 - 环境变量

QML——添加自定义模块

设置完成后,Qt Creator中可能不会立即生效,不过重启一下就好了。

如果不想麻烦地修改电脑设置中的环境变量,我们可以直接在代码中添加:

qputenv("QML2_IMPORT_PATH", "C:/Users/kong/Documents/StyleDemo");

方法二:

在代码中,调用 QQmlEngine::addImportPath() 方法添加路径。

最后,我们的模块就设计成功并能使用了。

上面的例子很简单,更多深刻的地方需要自己在学习和实践中探索!

例子:DefineAndUseModule/StyleDemo

使用时请根据这篇博客所说作相应修改。