Qt实例分析——C++定义的类创建为供QML使用的插件

1、首先我们需要继承QQmlExtensionPlugin类,这是一个抽象基类,提供了可供QML装载的插件。

2、接着我们需要在其子类中使用Q_PLUGIN_METADATA宏将其这个插件注册到Qt的元对象系统中。

3、重写纯虚函数registerTypes(),并在其中使用qmlRegisterType()注册插件中的QML类型,这与我们之前在main函数中做的一样。

4、然后我们需要编写一个插件的工程文件,包括TEMPLATE、CONFIG、DESTDIR、TARGET等等。

5、最后,我们还需要创建一个qmldir文件来描述这个插件。

这实际上是两个工程,我们完全可以单独编译import来生成dll插件,然后放在合适的地方供app工程使用。我们先来看import工程中的文件

chartsplugin.h:

#ifndef CHARTSPLUGIN_H
#define CHARTSPLUGIN_H
//![0]
#include <QQmlExtensionPlugin>
class ChartsPlugin : public QQmlExtensionPlugin     // 继承QQmlExtensionPlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")  // 为这个插件定义了一个唯一的接口,并注册至元对象系统
public:
    void registerTypes(const char *uri);           // 注册类型函数重载
}; 
//![0]
#endif
chartsplugin.cpp:

#include "chartsplugin.h"
//![0]
#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");
}
//![0]
可以看到QML插件注册的代码也很间断,但真正的实现还在于下面两个文件:

qmldir这个文件只有两句话:

module Charts            // 定义了组件名称空间为Charts,这个名称也是我们最后import时使用的
plugin chartsplugin      // 定义插件,与上面的chartsplugin一致
然后是我们的import.pro文件:

TEMPLATE = lib           // 生成库文件
CONFIG += plugin         // 该库是一个插件
QT += qml quick

DESTDIR = ../Charts      // 从Debug目录跳出到Build目录,并建立Charts目录,以存放dll与qmldir文件
TARGET = $$qtLibraryTarget(chartsplugin)

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

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

DESTPATH=$$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending/chapter6-plugins/Charts // 设置了一个变量指向这个Charts目录

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

OTHER_FILES += qmldir

# Copy the qmldir file to the same folder as the plugin binary
QMAKE_POST_LINK += $$QMAKE_COPY $$replace($$list($$quote($$PWD/qmldir) $$DESTDIR), /, $$QMAKE_DIR_SEP)
这样,在这个工程编译后,我们将在build目录中的Charts文件夹中找到我们的chartsplugind.dll与qmldir文件。d表示由debug编译产生。

接下来的app项目调用了这个插件并绘制了这个饼状图:

app.qml:

import QtQuick 2.0
import Charts 1.0   // 这里会有一条红色波浪线,QtCreator会抱怨可能找不到这个模块
                    // 你可以不管它,也可以设置qmlplugindump让QtQuick获知到这个模块的信息
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
            }
        ]
    }
}
main.cpp中不需要做额外的工作:

#include <QtQuick/QQuickView>
#include <QGuiApplication>
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQuickView view;
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.setSource(QUrl("qrc:///app.qml"));
    view.show();
    return app.exec();
}
app.pro:

TARGET = chapter6-plugins            // 设置项目名
QT += qml quick
# Avoid going to debug/release subdirectory
# so that our application will see the
# import path for the Charts module.
win32: DESTDIR = ./                 // 这一句将程序从debug移到上级build目录,也就是Charts的同级目录,这样使得程序可以到上面生成的插件
SOURCES += main.cpp
RESOURCES += app.qrc
最后还有一个根工程文件chapter6-plugins.pro:

TEMPLATE = subdirs        // 编译下面SUBDIRS定义的子目录
CONFIG += ordered         // 顺序编译,可能是基于效率不太被推荐,不过在这个小例子中就无所谓了
SUBDIRS = \
          import \        // 先编译import目录里的工程
          app.pro         // 然后编译app工程







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值