插件内容(Plugin Content)

插件是一个已定义接口的库,它只在需要时才被加载。这与一个库在程序启动时被链接和加载不同。在QML场景下,这个接口叫做QQmlExtensionPlugin。我们关心其中的两个方法initializeEngine()registerTypes()。当插件被加载时,首先会调用initializeEngine(),它允许我们访问引擎将插件对象暴露给根上下文。大多数时候你只会使用到registerTypes()方法。它允许你注册你自定义的QML类型到引擎提供的地址上。

我们稍微退一步考虑一个潜在的文件IO类型,它允许我们在QML中读取/写入一个小型文本文件。第一次的迭代可能看起来像在嘲笑QML的实现。

  1. // FileIO.qml (good)
  2. QtObject {
  3. function write(path, text) {};
  4. function read(path) { return "TEXT"}
  5. }

这是一个纯粹的qml可能的实现,C++基于QML编程接口来探索一些编程接口。我们看到我们有一个读取和写入函数。写入函数需要一个路径和一个文本,读取函数需要一个路径,返回一个文本。路径和文本看起来是公共参数,或许我们可以将它们提取作为属性。

  1. // FileIO.qml (better)
  2. QtObject {
  3. property url source
  4. property string text
  5. function write() { // open file and write text };
  6. function read() { // read file and assign to text };
  7. }

当然这看起来更像一个QML编程接口。我们使用属性让我们的环境能够绑定我们的属性并且响应变化。

在C++中创建这个编程接口我们需要创建类似的一个接口。

  1. class FileIO : public QObject {
  2. ...
  3. Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
  4. Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
  5. ...
  6. public:
  7. Q_INVOKABLE void read();
  8. Q_INVOKABLE void write();
  9. ...
  10. }

QML引擎需要注册FileIO类型。我们想要在org.example.io模块中使用它。

  1. import org.example.io 1.0
  2. FileIO {
  3. }

一个插件可以在相同的模块中暴露若干个类型。但是不能从一个插件中暴露若干个模块。所以模块与插件之间的关系是一对一的。这个关系由模块标识符表示。