Qt Reference Documentation

# Chapter 6: Writing an Extension Plugin

Files:

- declarative/tutorials/extending/chapter6-plugins/app.qml
- declarative/tutorials/extending/chapter6-plugins/chartsplugin.cpp
- declarative/tutorials/extending/chapter6-plugins/chartsplugin.h
- declarative/tutorials/extending/chapter6-plugins/piechart.cpp
- declarative/tutorials/extending/chapter6-plugins/piechart.h
- declarative/tutorials/extending/chapter6-plugins/pieslice.cpp
- declarative/tutorials/extending/chapter6-plugins/pieslice.h
- declarative/tutorials/extending/chapter6-plugins/chapter6-plugins.pro
- declarative/tutorials/extending/chapter6-plugins/qmldir

Currently the `PieChart` and `PieSlice` types are used by `app.qml`, which is displayed using a QDeclarativeView in a C++ application. An alternative way to use our QML extension is to create a plugin library to make it available to the QML engine. This allows `app.qml` to be loaded with the QML Viewer (or some other QML runtime application) instead of writing a `main.cpp` file and loading our own C++ application.

To create a plugin library, we need:

- A plugin class that registers our QML types
- A project file that describes the plugin
- A qmldir file that tells the QML engine to load the plugin

First, we create a plugin class named `ChartsPlugin`. It subclasses QDeclarativeExtensionPlugin and registers our QML types in the inherited registerTypes() method. It also calls Q_EXPORT_PLUGIN2 for Qt's plugin system.

Here is the `ChartsPlugin` definition in `chartsplugin.h`:

     #include <QDeclarativeExtensionPlugin>

     class ChartsPlugin : public QDeclarativeExtensionPlugin
     {
         Q_OBJECT
     public:
         void registerTypes(const char *uri);
     };

And its implementation in `chartsplugin.cpp`:

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

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

     Q_EXPORT_PLUGIN2(chartsplugin, ChartsPlugin);

Then, we write a `.pro` project file that defines the project as a plugin library and specifies with DESTDIR that library files should be built into a "lib" subdirectory:

     TEMPLATE = lib
     CONFIG += qt plugin
     QT += declarative

     DESTDIR = lib
     OBJECTS_DIR = tmp
     MOC_DIR = tmp

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

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

     symbian {
         include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
         TARGET.EPOCALLOWDLLDATA = 1
     }

Finally, we add a qmldir file that is automatically parsed by the QML engine. In this file, we specify that a plugin named "chapter6-plugin" (the name of the example project) can be found in the "lib" subdirectory:

     plugin chapter6-plugins lib

Now we have a plugin, and instead of having a main.cpp and an executable, we can build the project and then load the QML file in the QML Viewer:

     qmlviewer app.qml

(On Mac OS X, you can launch the "QMLViewer" application instead.)

Notice the "import Charts 1.0" statement has disappeared from `app.qml`. This is because the `qmldir` file is in the same directory as `app.qml`: this is equivalent to having PieChart.qml and PieSlice.qml files inside the project directory, which could both be used by `app.qml` without import statements.