C++&QML混合编程官方案例(五)(六)

Chapter 5: Using List Property Types(章节五:使用列表类型)

extending-qml/chapter5-listproperties

目前,一个PieChart只能有一个PieSlice。理想情况下,图表应该有多个不同颜色和大小的切片。为此,我们可以有一个接受PieSlice项列表的Slices属性:

  import Charts 1.0
  import QtQuick 2.0

  Item {
      width: 300; height: 200

      PieChart {
          anchors.centerIn: parent
          width: 100; height: 100

          slices: [
              PieSlice {
                  anchors.fill: parent
                  color: "red"
                  fromAngle: 0; angleSpan: 110
              },
              PieSlice {
                  anchors.fill: parent
                  color: "black"
                  fromAngle: 110; angleSpan: 50
              },
              PieSlice {
                  anchors.fill: parent
                  color: "blue"
                  fromAngle: 160; angleSpan: 100
              }
          ]
      }
  }

为此,我们用声明为QQmlListProperty类型的Slices属性替换PieChart中的PieSlice属性。QQmlListProperty类允许在QML扩展中创建列表属性。我们用一个返回切片列表的Slices()函数替换PieSlice()函数,并添加一个内部append_Slice()函数(如下所述)。我们还使用QList将内部切片列表存储为m_Slices:

class PieChart : public QQuickItem
  {
      Q_OBJECT
      Q_PROPERTY(QQmlListProperty<PieSlice> slices READ slices)
      ...
  public:
      ...
      QQmlListProperty<PieSlice> slices();

  private:
      static void append_slice(QQmlListProperty<PieSlice> *list, PieSlice *slice);

      QString m_name;
      QList<PieSlice *> m_slices;
  };

尽管Slices属性没有关联的写入函数,但由于QQmlListProperty的工作方式,它仍然是可修改的。
在Piechart实现中,我们实现Piechart::Slices()以返回QQmlListProperty值,并指示无论何时从QML请求向列表添加项目时都要调用内部Piechart::append_Slice()函数:

QQmlListProperty<PieSlice> PieChart::slices()
  {
      return QQmlListProperty<PieSlice>(this, nullptr, &PieChart::append_slice, nullptr, nullptr, nullptr);
  }

  void PieChart::append_slice(QQmlListProperty<PieSlice> *list, PieSlice *slice)
  {
      PieChart *chart = qobject_cast<PieChart *>(list->object);
      if (chart) {
          slice->setParentItem(chart);
          chart->m_slices.append(slice);
      }
  }

Append_Slice()函数只需像以前一样设置父项,并将新项添加到m_slices列表。
如您所见,QQmlListProperty的Append函数是用两个参数调用的:List属性和要追加的项。
PieSlice类也进行了修改,以包括FromAngel和angleSpan属性,并根据这些值绘制切片。

Chapter 6: Writing an Extension Plugin(章节六:编写一个扩展插件)

extending-qml/chapter6-plugins
目前app.qml使用PieChart和PieSlice类型,它在C++应用程序中使用QQuickView显示。
使用我们的QML扩展的另一种方法是创建一个插件库,使其作为新的QML导入模块可供QML引擎使用。
这允许Piehart和PieSlice类型注册到可由任何QML应用程序导入的类型命名空间中,而不是将这些类型限制为仅由一个应用程序使用。
创建QML的C++插件中介绍了创建插件的步骤。
首先,我们创建一个名为ChartsPlugin的插件类。
它将QQmlExtensionPlugin子类化,并在继承的registerTypes()方法中注册我们的QML类型。
以下是chartplugin.h中的ChartsPlugin定义:

 #include <QQmlExtensionPlugin>

  class ChartsPlugin : public QQmlExtensionPlugin
  {
      Q_OBJECT
      Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)

  public:
      void registerTypes(const char *uri);
  };

及其在chartplugin.cpp中的实现:

  #include "piechart.h"
  #include "pieslice.h"
  #include <qqml.h>

  void ChartsPlugin::registerTypes(const char *uri)
  {
      qmlRegisterType<PieChart>(uri, 1, 0, "PieChart");
      qmlRegisterType<PieSlice>(uri, 1, 0, "PieSlice");
  }

然后,我们编写一个.pro项目文件,该文件将项目定义为插件库,并使用DESTDIR指定库文件应构建到…/Charts目录中。

  TEMPLATE = lib
  CONFIG += plugin
  QT += qml quick

  DESTDIR = ../Charts
  TARGET = $$qtLibraryTarget(chartsplugin)

  HEADERS += piechart.h \
             pieslice.h \
             chartsplugin.h

  SOURCES += piechart.cpp \
             pieslice.cpp \
             chartsplugin.cpp

  DESTPATH=$$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter6-plugins/Charts

  target.path=$$DESTPATH
  qmldir.files=$$PWD/qmldir
  qmldir.path=$$DESTPATH
  INSTALLS += target qmldir

  CONFIG += install_ok  # Do not cargo-cult this!

  OTHER_FILES += qmldir

  # Copy the qmldir file to the same folder as the plugin binary
  cpqmldir.files = qmldir
  cpqmldir.path = $$DESTDIR
  COPIES += cpqmldir

在Windows或Linux上构建此示例时,Charts目录将与使用新导入模块的应用程序位于同一级别。
这样,QML引擎将找到我们的模块,因为QML导入的默认搜索路径包括应用程序可执行文件的目录。
在MacOS上,插件二进制文件被复制到应用程序包中的Contents/Plugin中;此路径 chapter6-plugins/app.pro:

 osx {
      charts.files = $$OUT_PWD/Charts
      charts.path = Contents/PlugIns
      QMAKE_BUNDLE_DATA += charts
  }

为此,我们还需要在main.cpp中添加此位置作为QML导入路径:

      QQuickView view;
  #ifdef Q_OS_OSX
      view.engine()->addImportPath(app.applicationDirPath() + "/../PlugIns");
  #endif
      ...

当有多个应用程序使用相同的QML导入时,定义自定义导入路径也很有用。
Pro文件还包含额外的魔力,以确保始终将模块定义qmldir文件复制到与插件二进制文件相同的位置。
Qmldir文件声明模块名称和模块提供的插件:

  module Charts
  plugin chartsplugin

现在我们有了一个可以导入到任何应用程序的QML模块,只要QML引擎知道在哪里可以找到它。
该示例包含一个加载app.qml的可执行文件,该文件使用IMPORT Charts 1.0版本。
或者,也可以使用qmlScene工具加载QML文件,将导入路径设置为当前目录,以便找到qmldir文件:

  qmlscene -I . app.qml

模块“Charts”将由QML引擎加载,该模块提供的类型将可用于任何导入它的QML文档。

教程完。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值