2012-02-05 18 views
2

プラグインを持つプラグインでもアプリケーションを作りたいと思っています(メインアプリケーションはこれを知る必要はありません)。理由は、私はいくつかのコードプロジェクトのための一般的なIDEを作成する、私はイメージハンドラのプラグインを作成することです。私は、イメージハンドラプラグインが、メインアプリケーションが知る必要のない独自のフィルタプラグインをいくつか持っていることを望みます。これは可能ですか?私はいくつかのインタフェースを持っている主なIDEをしたいと思いQt PluginFramework。プラグインでプラグインを宣言する

:ここ

は、私は私の自己を得たものです。

class IDocumentFactory 
{ 
public: 
    virtual ~IDocumentFactory() {} 

    //virtual QStringList documents() const = 0; 
    virtual QVector<FileOpenEntries> name_filters() const = 0; 
    virtual QWidget* open_document(QWidget* parent, 
            const QStringList &filepaths, 
            const QString &name_filter_key) const = 0; 

}; 
Q_DECLARE_INTERFACE(IDocumentFactory,  "S-DAIDE.IDocumentFactory/1.0") 
class IDeclarePlugins 
{ 
public: 
    virtual ~IDeclarePlugins() {} 

    virtual QStringList plugins() const = 0; 
    virtual void load_plugings(QObject * plugins) = 0; 
}; 
Q_DECLARE_INTERFACE(IDeclarePlugins,  "S-DAIDE.IDeclarePlugins/1.0") 

ここで、他のプラグインが実装できるインターフェイスを自分のプラグインに定義したいと思います。

class MyPlugin : public QObject, IDeclarePlugins 
{ 
    Q_OBJECT 
    Q_INTERFACES(IDeclarePlugins) 

    ... 
    QStringList ImagePlugin::plugins() const 
    { 
    return QStringList() << "S-DAIDE.ImagePlugin.IOverlay/1.0"; 
    } 
} 

私の主なアプリをロードするプラグインです。

foreach (QString fileName, m_plugins_dir.entryList(QDir::Files)) { 

     QPluginLoader loader(m_plugins_dir.absoluteFilePath(fileName)); 
     QObject *plugin = loader.instance(); 

} 

は、プラグインがQ_DECLARE_INTERFACEで使用される文字列に基づいてインターフェイスを実装しているかどうかを確認する方法が存在しています。このような私はそれを設計することによりvirtual QStringList plugins() const = 0;

答えて

1

で宣言する他のすべてのプラグインは、あなたがqobject_castクラスをインタフェースする必要がありますが、それらのidsを使用しないプラグインのロードを行うことができます。

プラグインごとにidを返す関数QString id()を作成することはできますが、その結果をローダーコードで確認できます。

あなたのプラグインがidを与えている場合は、原則として、あなたはQ_DECLARE_INTERFACEマクロdefenitionでそれを行うための方法を見つけることができます、あなたが望むように、確認することができます。

bool isIdMatch = const_cast<QObject *>(object)->qt_metacast(IId) != 0; 

しかしqt_metacastが文書化されていないので、私はあなたがこの方法を使用することをお勧めしません。

#define DECLARE_ID(__iid) \ 
    virtual QString id() const {return iid_private();}\ 
    static const char* const iid_private() {return __iid;} 

#define GET_ID(IFace) IFace::iid_private() 

class IFace 
{ 
public: 
    DECLARE_ID("Iface") 
}; 
Q_DECLARE_INTERFACE(IFace, GET_ID(IFace)) 

class IFace2: public IFace 
{ 
public: 
    DECLARE_ID("Iface2") 
}; 
Q_DECLARE_INTERFACE(IFace2,GET_ID(IFace2)) 


int main(int c, char**v) 
{ 
    IFace* f = new IFace2(); 
    qDebug() << f->id() << f->iid_private(); 
    qDebug() << GET_ID(IFace) <<GET_ID(IFace2); 
    return 0;//a.exec(); 
} 

研究かわりiid_privateid()機能を使用する必要があることを出力し、注意を、:ので、自分自身を愛するQtのフレームワークという

あなたが繰り返し書いIDSを取り除く2倍にしたい場合は、マクロを使用することができ、

+0

私のクラスにQString id()const {return "S-DAIDE.ImagePlugin.IOverlay/1.0";}を追加し、Q_DECLARE_INTERFACE(IOverlay、\t "S-DAIDE.ImagePlugin.IOverlay/1.0")も持っています。 。すべてのプラグインにIDがあること。戻りメソッドとQ_DECLARE_INTERFACEの両方の "S-DAIDE.ImagePlugin.IOverlay/1.0"を書き込む冗長性を減らす方法はありますか? –

+0

@ s093294、編集した私の答え – Lol4t0

+0

いいですね。最後の1つの質問。 QString id()const = 0を持つベースプラグインクラスを作成して、ユーザーにIDを宣言するようにしたいでしょうか。構築時にカスタムエラーのようなものを追加する方法はありますか?ユーザーがプラグインクラス内でDECLARE_IDを呼び出さなかった場合、そのことについてユーザーに通知します。 –

関連する問題