# 插件内容
插件是带有已定义接口的库,可按需加载。 它与库不同,因为库是在应用程序启动时链接和加载的。 在QML中,该接口称为QQmlExtensionPlugin
。 这里提供了两个有趣的方法:initializeEngine()
和registerTypes()
。 当插件被加载时,首先调用initializeEngine()
,它允许访问引擎以将插件对象暴露给根上下文。 大多数情况下,只会使用registerTypes()
方法,它允许通过提供的URL向引擎注册自定义的QML类型。
这里通过构建一个小的功能类FileIO
来探索插件的使用。 此类可以从QML中读取和写入文本文件。 在模拟的QML实现中,第一次迭代的代码可能看起来如下所示:
// FileIO.qml (good)
QtObject {
function write(path, text) {};
function read(path) { return "TEXT" }
}
这是一个纯QML的实现,它可能的基于C++的QML API。 这里使用它来探索API实现。 可以看到这里需要一个read
和一个write
函数。 还可以看到write
函数接受一个path
和一个text
参数,而read
函数接受一个path
参数并返回一个text
。 看起来,path
和text
是通用参数,也许可以将它们提取为属性,以使API在声明性上下文中更易于使用。
// FileIO.qml (better)
QtObject {
property url source
property string text
function write() {} // open file and write text
function read() {} // read file and assign to text
}
是的,这看起来更像是一个QML API。 使用属性来允许环境绑定到属性并对更改做出反应。
要在C++中创建这个API,需要创建一个如下所示的Qt C++接口:
class FileIO : public QObject {
...
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
...
public:
Q_INVOKABLE void read();
Q_INVOKABLE void write();
...
}
FileIO
类型需要在QML引擎中注册。 想在"org.example.io"模块下使用它,如下所示:
import org.example.io 1.0
FileIO {
}
一个插件可以使用同一个模块暴露几种类型,但不能从一个插件中暴露多个模块。 所以模块和插件之间是一对一的关系。 这种关系由模块标识符表示。