このページでは

Qtプラグインの作成方法

Qt には、プラグインを作成するための 2 つの API が用意されています:

  • Qt自体への拡張機能(カスタムデータベースドライバ、画像フォーマット、テキストコーデック、スタイルなど)を作成するための高レベルAPI。
  • Qtアプリケーションを拡張するための低レベルAPI。

たとえば、カスタムQStyle サブクラスを作成し、Qtアプリケーションでそれを動的に読み込ませたい場合は、高レベルAPIを使用します。

高レベルAPIは低レベルAPIの上に構築されているため、両者に共通する問題もいくつかあります。

Qt Widgets Designer で使用するプラグインを提供したい場合は、「カスタムウィジェットプラグインの作成」を参照してください。

高レベルAPI:Qt拡張機能の作成

Qt自体を拡張するプラグインを作成するには、適切なプラグインの基底クラスをサブクラス化し、いくつかの関数を実装し、マクロを追加します。

プラグインの基底クラスはいくつかあります。派生プラグインは、デフォルトでは標準のプラグインディレクトリのサブディレクトリに保存されます。適切なディレクトリに保存されていない場合、Qt はそのプラグインを認識しません。

次の表は、プラグインの基底クラスをまとめたものです。一部のクラスはプライベートであるため、ドキュメントには記載されていません。これらを使用することは可能ですが、将来の Qt バージョンとの互換性は保証されません。

基底クラスディレクトリ名Qt モジュールキーの大文字小文字の区別
QAccessibleBridgePluginaccessiblebridgeQt GUI大文字小文字を区別する
QImageIOPluginimageformatsQt GUI大文字と小文字を区別
QPictureFormatPlugin (非推奨)pictureformatsQt GUI大文字と小文字を区別
QBearerEnginePluginbearerQt Network大文字と小文字を区別する
QPlatformInputContextPluginplatforminputcontextsQt プラットフォーム抽象化大文字と小文字を区別しない
QPlatformIntegrationPluginplatformsQt プラットフォーム抽象化大文字小文字を区別しない
QPlatformThemePluginplatformthemesQt プラットフォーム抽象化大文字小文字を区別しない
QPlatformPrinterSupportPluginprintsupportQt Print Support大文字小文字を区別しない
QSGContextPluginscenegraphQt Quick大文字と小文字を区別する
QSqlDriverPluginsqldriversQt SQL大文字と小文字を区別する
QIconEnginePluginiconenginesQt SVG大文字小文字を区別しない
QAccessiblePluginaccessibleQt Widgets大文字と小文字を区別する
QStylePluginstylesQt Widgets大文字小文字を区別しない

JsonViewer という名前の新しいドキュメントビューアクラスをプラグインとして利用可能にしたい場合、そのクラスは次のように定義する必要があります(jsonviewer.h ):

class JsonViewer : public ViewerInterface
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.DocumentViewer.ViewerInterface/1.0" FILE "jsonviewer.json")
    Q_INTERFACES(ViewerInterface)
public:
    JsonViewer();
    ~JsonViewer() override;
private:
    void retranslate() override;
    bool openJsonFile();

    QTreeView *m_tree = nullptr;
    QListWidget *m_toplevel = nullptr;
    QJsonDocument m_root;
    QAction *m_expandAllAction = nullptr;
    QAction *m_collapseAllAction = nullptr;
};

クラス実装が `.cpp ` ファイル内にあることを確認してください:

JsonViewer::JsonViewer()
    : m_expandAllAction(new QAction(this)),
      m_collapseAllAction(new QAction(this))

{
    connect(this, &AbstractViewer::uiInitialized, this, &JsonViewer::setupJsonUi);

    m_expandAllAction->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::ZoomIn));
    m_collapseAllAction->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::ZoomOut));
}

void JsonViewer::init(QFile *file, QWidget *parent, QMainWindow *mainWindow)
{
    AbstractViewer::init(file, new QTreeView(parent), mainWindow);
    setTranslationBaseName("jsonviewer"_L1);
    m_tree = qobject_cast<QTreeView *>(widget());
}

また、ほとんどのプラグインでは、プラグインを記述するメタデータを含む json ファイル(jsonviewer.json )が必要です。ドキュメントビューアプラグインの場合、このファイルにはビューアプラグインの名前のみが含まれます。

{ "Keys": [ "jsonviewer" ] }

JSON ファイルに記述すべき情報の種類は、プラグインによって異なります。ファイルに含めるべき情報の詳細については、クラスのドキュメントを参照してください。

データベースドライバ、画像フォーマット、テキストコーデック、およびその他のほとんどのプラグインタイプについては、明示的なオブジェクトの作成は不要です。Qtが必要に応じてそれらを検出し、作成します。

プラグインクラスによっては、追加の関数の実装が必要になる場合があります。各プラグインタイプごとに再実装が必要な仮想関数の詳細については、クラスのドキュメントを参照してください。

「Document Viewer Demo」では、ファイルの構造化されたコンテンツを表示するプラグインの実装方法を示しています。したがって、各プラグインは仮想関数を再実装しており、その

  • プラグインを識別し
  • サポートするMIMEタイプを返す
  • 表示するコンテンツの有無を通知し、
  • コンテンツの表示方法を指定します
    QString viewerName() const override { return QLatin1StringView(staticMetaObject.className()); };
    QStringList supportedMimeTypes() const override;
    bool hasContent() const override;
    bool supportsOverview() const override { return true; }

低レベルAPI:Qtアプリケーションの拡張

Qt自体に加え、Qtアプリケーションはプラグインを通じて拡張することができます。これには、アプリケーションがQPluginLoader を使用してプラグインを検出し、読み込む必要があります。その文脈において、プラグインは任意の機能を提供することができ、データベースドライバ、画像フォーマット、テキストコーデック、スタイル、およびQtの機能を拡張するその他の種類のプラグインに限定されるものではありません。

プラグインを通じてアプリケーションを拡張可能にするには、以下の手順が必要です:

  1. プラグインとの通信に使用する一連のインターフェース(純粋仮想関数のみを持つクラス)を定義します。
  2. Q_DECLARE_INTERFACE() マクロを使用して、Qtのメタオブジェクトシステムにそのインターフェースを通知します。
  3. アプリケーション内で `QPluginLoader ` を使用してプラグインを読み込みます。
  4. qobject_cast() を使用して、プラグインが指定されたインターフェースを実装しているかどうかをテストします。

プラグインの作成には、以下の手順が含まれます:

  1. QObject およびプラグインが提供したいインターフェースを継承するプラグインクラスを宣言します。
  2. Q_INTERFACES() マクロを使用して、Qtのメタオブジェクトシステムにインターフェースを通知します。
  3. Q_PLUGIN_METADATA() マクロを使用して、プラグインをエクスポートします。

例えば、インターフェースクラスの定義は次のようになります:

class ViewerInterface : public AbstractViewer
{
public:
    virtual ~ViewerInterface() = default;
};

インターフェースの宣言は次のとおりです:

#define ViewerInterface_iid "org.qt-project.Qt.Examples.DocumentViewer.ViewerInterface/1.0"
Q_DECLARE_INTERFACE(ViewerInterface, ViewerInterface_iid)

Qt Widgets Designer に特有の課題については、「Qt Widgets Designer 用のカスタムウィジェットの作成」も参照してください。プラグインを使用してカスタムカレンダーシステムのサポートを追加する例については、「カレンダーバックエンドプラグインの例」を参照してください。

プラグインの検索

プラグインは標準のプラグインサブディレクトリに格納されているため、Qt アプリケーションは利用可能なプラグインを自動的に認識します。このため、Qt が自動的に処理を行うため、アプリケーション側でプラグインを検索・読み込むためのコードは一切必要ありません。

開発中は、プラグインのディレクトリは `QTDIR/plugins ` になります(ここで `QTDIR ` は Qt がインストールされているディレクトリです)。各種類のプラグインは、その種類ごとのサブディレクトリ(例:`styles`)に格納されます。 アプリケーションでプラグインを使用したいが、標準のプラグインパスを使用したくない場合は、インストールプロセスでプラグインに使用するパスを指定し、そのパスを保存しておいてください。たとえば、QSettings を使用して、アプリケーションの実行時に読み込めるようにします。 そうすれば、アプリケーションはこのパスを引数として `QCoreApplication::addLibraryPath()` を呼び出すことができ、プラグインをアプリケーションから利用できるようになります。なお、パスの末尾部分(例:styles )は変更できない点に注意してください。

プラグインをロード可能にするには、アプリケーションの直下にサブディレクトリを作成し、そのディレクトリにプラグインを配置するという方法があります。 Qt に付属するプラグイン(plugins ディレクトリにあるもの)を配布する場合は、プラグインが置かれているplugins 配下のサブディレクトリを、アプリケーションのルートフォルダにコピーする必要があります(つまり、plugins ディレクトリは含めないでください)。

デプロイに関する詳細については、『Qt アプリケーションのデプロイ』および『プラグインのデプロイ』のドキュメントを参照してください。

静的プラグイン

アプリケーションにプラグインを組み込むための一般的かつ最も柔軟な方法は、プラグインをダイナミックライブラリにコンパイルし、それを別々に配布して、実行時に検出・読み込ませることです。

プラグインをアプリケーションに静的にリンクすることも可能です。Qtの静的バージョンをビルドする場合、Qtの定義済みプラグインを組み込むにはこれが唯一の選択肢となります。静的プラグインを使用すると、デプロイ時のエラーが少なくなりますが、アプリケーションを完全に再ビルドして再配布しなければ、プラグインの機能を追加できないという欠点があります。

CMake および qmake は、使用される Qt モジュールで通常必要とされるプラグインを自動的に追加しますが、より特殊なプラグインについては手動で追加する必要があります。自動的に追加されるプラグインのデフォルトリストは、タイプごとに上書き可能です。

デフォルト設定は、そのままでも最適な動作が得られるよう調整されていますが、アプリケーションを不必要に肥大化させる可能性があります。リンカーのコマンドラインを確認し、不要なプラグインを削除することをお勧めします。

静的プラグインを実際にリンクおよびインスタンス化させるには、アプリケーションコード内にQ_IMPORT_PLUGIN() マクロも必要ですが、これらはビルドシステムによって自動的に生成され、アプリケーションプロジェクトに追加されます。

CMake での静的プラグインのインポート

CMake プロジェクトでプラグインを静的にリンクするには、qt_import_plugins()コマンドを呼び出す必要があります。

たとえば、Linux用のlibinput プラグインは、デフォルトではインポートされません。次のコマンドでインポートします:

qt_import_plugins(myapp INCLUDE Qt::QLibInputPlugin)

デフォルトのQt Platform Adaptationプラグインの代わりに、最小限のプラットフォーム統合プラグインをリンクするには、次のように指定します:

qt_import_plugins(myapp
    INCLUDE_BY_TYPE platforms Qt::MinimalIntegrationPlugin
)

もう1つの典型的な使用例として、特定のimageformats プラグインセットのみをリンクする場合があります:

qt_import_plugins(myapp
    INCLUDE_BY_TYPE imageformats Qt::QJpegPlugin Qt::QGifPlugin
)

imageformats プラグインのリンクを一切行いたくない場合は、次のように指定してください:

qt_import_plugins(myapp
    EXCLUDE_BY_TYPE imageformats
)

デフォルトのプラグインの追加を無効にしたい場合は、qt_import_plugins() のNO_DEFAULT オプションを使用してください。

qmake での静的プラグインのインポート

qmakeプロジェクトでは、QTPLUGIN を使用して、必要なプラグインをビルドに追加する必要があります:

QTPLUGIN += qlibinputplugin

たとえば、デフォルトの Qt Platform Adaptation プラグインの代わりに minimal プラグインをリンクするには、次のように指定します:

QTPLUGIN.platforms = qminimal

デフォルトのQPAプラグインもミニマルQPAプラグインも自動的にリンクされたくない場合は、次のように指定します:

QTPLUGIN.platforms = -

QTPLUGINに追加されたすべてのプラグインが自動的にリンクされるのを防ぎたい場合は、CONFIG 変数からimport_plugins を削除してください:

CONFIG -= import_plugins

静的プラグインの作成

また、以下の手順に従って、独自の静的プラグインを作成することも可能です:

  1. CMakeLists.txt内のqt_add_plugin()コマンドに、STATIC オプションを指定します。qmakeプロジェクトの場合は、プラグインの.pro ファイルにCONFIG += static を追加します。
  2. アプリケーション内でQ_IMPORT_PLUGIN() マクロを使用してください。
  3. プラグインに qrc ファイルが含まれている場合は、アプリケーション内でQ_INIT_RESOURCE() マクロを使用してください。
  4. CMakeLists.txt ファイル内のtarget_link_libraries、または.pro ファイル内のLIBS を使用して、アプリケーションをプラグインライブラリとリンクします。

具体的な手順については、「Plug & Paint」のサンプルおよび関連するBasic Toolsプラグインを参照してください。

注: プラグインのビルドに CMake または qmake を使用していない場合は 、QT_STATICPLUGIN プリプロセッサマクロが定義されていることを確認する必要があります。

プラグインの読み込み

プラグインの種類(静的または共有)やオペレーティングシステムによって、プラグインの検索および読み込み方法に固有のアプローチが必要となります。プラグインの読み込みのための抽象化を実装しておくと便利です。

void ViewerFactory::loadViewerPlugins()
{
    if (!m_viewers.isEmpty())
        return;

QPluginLoader::staticInstances()は、静的にリンクされた各プラグインへのポインタを持つQObjectList を返します

    // Load static plugins
    const QObjectList &staticPlugins = QPluginLoader::staticInstances();
    for (auto *plugin : staticPlugins)
        addViewer(plugin);

共有プラグインはそれぞれのデプロイメントディレクトリに配置されますが、これにはOS固有の処理が必要になる場合があります。

   // 共有プラグインを読み込む
    QDir pluginsDir=QDir(QApplication::applicationDirPath());
#if defined(Q_OS_DARWIN)
    if(pluginsDir.exists("../PlugIns"_L1)) {// インストール済みビルド
        pluginsDir.cd("../PlugIns"_L1);
    }else{
        pluginsDir.cd("../../../../plugins"_L1);// インストールされていないビルド
    }
#elif defined(Q_OS_WIN)
    if(pluginsDir.exists("plugins"_L1)) {// インストールされていないビルド
        pluginsDir.cd("plugins"_L1);
    }else{
        pluginsDir.cd("../plugins"_L1);// インストール済みビルド
    }
#else
    pluginsDir.cd("../plugins"_L1);// インストール済みおよび未インストールビルド
#endif

   // qDebug("%s からプラグインを読み込んでいます...", qUtf8Printable(pluginsDir.path()));
    const autoentryList=pluginsDir.entryList(QDir::Files);
    for(constQString&fileName: entryList) {
        QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
        QObject*plugin =loader.instance();
        if(plugin)
            addViewer(plugin);
#if 0
        else
            qDebug() << loader.errorString();
#endif
    }
}

プラグインのデプロイとデバッグ

「プラグインのデプロイ」ドキュメントでは、アプリケーションへのプラグインのデプロイ手順や、問題が発生した際のデバッグ方法について解説しています。

「 QPluginLoader 」および「QLibrary 」も参照してください 。

© 2026 The Qt Company Ltd. 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.