Qt支持将用C++编写的自定义QML对象类型打包到一个QML扩展插件中。在运行时,QML引擎对这个插件加载后,就可以在QML程序中使用插件中定义QML对象类型了。通常,需要将扩展插件打包到一个模块中,并在QML程序中,通过import语句对模块进行引入,这样就可以在QML程序中使用扩展插件中定义的对象类型了。
Qt插件实际上是某个插件接口类型的实现。通常这个实现类的源码被编译为动态库,这样就可以在程序运行时动态加载并创建插件对象了。QML扩展插件也是Qt插件的一种,它是QQmlEngineExtensionPlugin接口的一个实现。
编写一个QML扩展插件需要如下步骤:
1、编写QQmlEngineExtensionPlugin子类,并用 Q_PLUGIN_METADATA()宏对子类进行注册
2、用 QML_ELEMENT 或 QML_NAMED_ELEMENT()声明QML对象类型
3、对工程文件进行配置。
下面会结合一个实例进行讲解:
class TimeModel : public QObject
{
Q_OBJECT
Q_PROPERTY(int hour READ hour NOTIFY timeChanged)
Q_PROPERTY(int minute READ minute NOTIFY timeChanged)
QML_NAMED_ELEMENT(Time)
...
class QExampleQmlPlugin : public QQmlEngineExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
};
//.pro文件
TEMPLATE = lib
CONFIG += qt plugin qmltypes
QT += qml
QML_IMPORT_NAME = TimeExample
QML_IMPORT_MAJOR_VERSION = 1
DESTDIR = imports/$$QML_IMPORT_NAME
TARGET = qmlqtimeexampleplugin
SOURCES += qexampleqmlplugin.cpp
在以上这个例子中,Time是一个用C++编写的对象类型。QExampleQmlPlugin是一个自定义QML扩展插件。
在QExampleQmlPlugin类中通过 Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)宏对它进行注册。
在.pro文件中,QML_IMPORT_NAME变量指定将自定义QML对象类型导入哪一个命名空间中。QML_IMPORT_MAJOR_VERSION变量指定了主版本编号。TARGET变量指定了生成的dll文件的文件名。DESTDIR 变量指定了生成文件的目录。TEMPLATE变量指定了当前工程是一个库工程。CONFIG变量中需要添加plugin qmltypes两个字符串,其中qmltypes字符串是注册QML对象类型所需要的,plugin字符串是注册插件所需要。
在实际使用时,还需要将插件打包到一个模块中,以下是一个打包示例:
//.qmldir文件
module TimeExample
Clock 1.0 Clock.qml
plugin qmlqtimeexampleplugin
模块是通过.qmldir文件定义的,在这个文件中,指定了模块包含qmlqtimeexampleplugin插件,以及Clock对象类型。并指定了模块的名字为TimeExample。
在QML程序中,如果想要使用扩展插件中的QML对象类型,需要对模块进行引入:
import TimeExample // import types from the plugin
Clock { // this class is defined in QML (imports/TimeExample/Clock.qml)
Time { // this class is defined in C++ (plugin.cpp)
id: time
}
hours: time.hour
minutes: time.minute
}
这样就可以在QML程序中使用插件中定义的对象类型了。