ContentPlugin Example
Demonstrates how to write a Content Plugin for QML Live.
The plugin written in this example displays images like the built-in Imageviewer in QML Live, but it shows the content rotated only works on *.png files.
We will start by reviewing the interface defined in contentadapterinterface.h
in the QML Live source code. This interface can be used to add a new ContentAdapter to QML Live. The ContentAdapter will be used to display any content that shouldn't be handled by the QML Live Runtime, like displaying an image.
class QMLLIVESHARED_EXPORT ContentAdapterInterface { public: enum Feature { QtQuickControls = 0x1 }; Q_DECLARE_FLAGS(Features, Feature) virtual ~ContentAdapterInterface() {} virtual void cleanUp() {} virtual bool canPreview(const QString& path) const = 0; virtual QImage preview(const QString& path, const QSize &requestedSize) = 0; virtual bool canAdapt(const QUrl& url) const = 0; virtual bool isFullScreen() const { return false; } void setAvailableFeatures(ContentAdapterInterface::Features features) { m_features = features; } ContentAdapterInterface::Features availableFeatures() { return m_features; } virtual QUrl adapt(const QUrl& url, QQmlContext* context) = 0; private: Features m_features; };
The ContentAdapterInterface
class declares four functions. The first function canAdapt(const QUrl&)
returns whether the plugin can display the given file or directory.
The second function adapt(const QUrl& url, QDeclarativeContext* context)
returns a custom QUrl which will be used by QML Live to display the given QUrl. The returned QUrl always has to point to a QML file used to display the content. To be able to control the returned QML file, context
can be used to set custom properties which will be exported to the QML file.
canPreview() and preview() are used for generating preview thumbnails. We use the easiest implementation for these two methods.
MyContentAdapterPlugin
class MyContentAdapterPlugin : public QObject, public ContentAdapterInterface { Q_OBJECT Q_INTERFACES(ContentAdapterInterface) Q_PLUGIN_METADATA(IID "io.qt.QMLLive.ContentPlugin") public: explicit MyContentAdapterPlugin(QObject *parent = 0); bool canPreview(const QString& path) const; QImage preview(const QString& path, const QSize &requestedSize); bool canAdapt(const QUrl& url) const; QUrl adapt(const QUrl& url, QQmlContext* context); };
The MyContentAdapterPlugin implements the interface to QML Live. It subclasses QObject and the required ContentAdapterInterface
.
Q_INTERFACES(ContentAdapterInterface)
The Q_INTERFACES
macro will be used to register the plugin to Qt's plugin system.
We have to overload the canAdapt(const QUrl&)
function if we want it to be called for the right file type: *.png." That's why we check the file ending on the given url and return true when it's a png file.
bool MyContentAdapterPlugin::canAdapt(const QUrl &url) const { return url.toLocalFile().endsWith(".png"); }
If the plugin accepts the file, adapt(const QUrl& url, QDeclarativeContext* context)
will be called. Here we export the path to the image as a special property in the context to be able to access the fileName from within our QML file. Afterwards we return a QUrl pointing to our QML file which is inside a ResourceFile.
QUrl MyContentAdapterPlugin::adapt(const QUrl &url, QQmlContext *context) { context->setContextProperty("imageSource", url); return QString("qrc:/mycontentadatperplugin/plugin.qml"); }
Now only the implementation of canPreview() and preview() are missing. Here we just add some dummy implementation because we don't want to add this functionality.
bool MyContentAdapterPlugin::canPreview(const QString &path) const { Q_UNUSED(path) return false; } QImage MyContentAdapterPlugin::preview(const QString &path, const QSize &requestedSize) { Q_UNUSED(path); Q_UNUSED(requestedSize); return QImage(); }
plugin.qml
The plugin.qml file is our ImageViewer. In it we create an Image Element
and set the source to our exported property imageSource
. The rotation property will be set to 180.
import QtQuick 1.1 Rectangle { width: 300 height: 300 Image { anchors.centerIn: parent rotation: 180 source: imageSource } }
The Resource File
Because we don't want to fiddle around with paths, we include our QML file into a resource file. It is important to use a unique prefix in the resource file in order to avoid conflicts with QML Live, which also uses resource files. The best approach is to use the plugin name as a prefix.
Files:
© 2019 Luxoft Sweden AB. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.