Sunday, July 21, 2013

Qt plugins applied to nomacs

Because nomacs is based on Qt I decided that the best way to create plugins is using the Qt QPluginLoader. First we need to create an interface that is the connection between nomacs and dlls:
class DkPluginInterface {
    virtual ~DkPluginInterface() {}

    virtual QString pluginID() const = 0;
    virtual QString pluginName() const = 0;
    virtual QString pluginDescription() const = 0;
    virtual QImage pluginDescriptionImage() const = 0;
    virtual QString pluginVersion() const = 0;

    virtual QStringList runID() const = 0;
    virtual QString pluginMenuName(const QString &runID) const = 0;
    virtual QString pluginStatusTip(const QString &runID) const = 0; 
    virtual QImage runPlugin(const QString &runID, const QImage &image) const = 0;

Q_DECLARE_INTERFACE(nmc::DkPluginInterface, "com.nomacs.ImageLounge.DkPluginInterface/0.1")
In the interface there are the functions that need to be implemented in the plugins. These are the function called from nomacs to retrieve plugin information and to run it. So that the QPluginLoader can know about the interface we have to declare it with Q_DECLARE_INTERFACE. The header file of a the plugin extends the above interface. Here is a test plugin header to show the import:
class DkFlipPlugin : public QObject, DkPluginInterface {

    QString pluginID() const;
    QString pluginName() const;
    QString pluginDescription() const;
    QImage pluginDescriptionImage() const;
    QString pluginVersion() const;

    QStringList runID() const;
    QString pluginMenuName(const QString &runID) const;
    QString pluginStatusTip(const QString &runID) const; 
    QImage runPlugin(const QString &runID, const QImage &image) const;
With Q_INTERFACES we let Qt know which interfaces the plugin uses. Just before the end of the plugin cpp file we need to export the plugin: Q_EXPORT_PLUGIN2(dkflipplugin, DkFlipPlugin). By doing this we tell Qt that class DkFlipPlugin is part of the plugin interface.

To build a Qt dll using cmake we need to add  the following lines to the cmake file:
 Now we have a plugin that we need to import into nomacs. We load the plugin using QPluginLoader from which we create a QObject instance that we cast to our DkPluginInterface class:
    QPluginLoader *loader = new QPluginLoader(filePath);
    QObject *plugin = loader->instance();
    if(plugin) {

        DkPluginInterface *initializedPlugin = qobject_cast<DkPluginInterface*>(plugin);
        if(initializedPlugin) {
            // do something with the plugin
    else delete loader;

No comments:

Post a Comment