Qtプラグインの作り方
Qtはプラグインを作成するための2つのAPIを提供しています:
- Qt プラグインを作成するための 2 つの API が用意されています: Qt プラグインを作成するための高レベル API。
- Qt アプリケーションを拡張するための低レベル API。
例えば、QStyle のサブクラスを作成し、Qt アプリケーションに動的に読み込ませたい場合は、高レベル API を使用します。
上位APIは下位APIの上に構築されているため、いくつかの問題は両方に共通です。
Qt Widgets Designer で使用するプラグインを提供したい場合は、Creating Custom Widget Plugins を参照してください。
高レベル API:Qt 拡張機能の記述
Qt 自体を拡張するプラグインを作成するには、適切なプラグイン基底クラスをサブクラス化し、いくつかの関数を実装し、マクロを追加します。
プラグインの基本クラスはいくつかあります。派生プラグインは、デフォルトでは標準プラグインディレクトリのサブディレクトリに格納されます。プラグインが適切なディレクトリに格納されていない場合、Qtはプラグインを見つけられません。
以下の表は、プラグインの基本クラスをまとめたものです。いくつかのクラスはプライベートなので、ドキュメント化されていません。それらを使用することはできますが、それ以降の Qt バージョンとの互換性は約束されていません。
基本クラス | ディレクトリ名 | Qt モジュール | 大文字と小文字の区別 |
---|---|---|---|
QAccessibleBridgePlugin | accessiblebridge | Qt GUI | 大文字小文字を区別する |
QImageIOPlugin | imageformats | Qt GUI | 大文字小文字を区別 |
QPictureFormatPlugin (廃止予定) | pictureformats | Qt GUI | 大文字小文字を区別 |
QBearerEnginePlugin | bearer | Qt Network | ケースセンシティブ |
QPlatformInputContextPlugin | platforminputcontexts | Qt プラットフォーム抽象化 | 大文字小文字を区別しない |
QPlatformIntegrationPlugin | platforms | Qt プラットフォーム抽象化 | 大文字小文字を区別しない |
QPlatformThemePlugin | platformthemes | Qt プラットフォーム抽象化 | 大文字小文字を区別しない |
QPlatformPrinterSupportPlugin | printsupport | Qt Print Support | 大文字小文字を区別しない |
QSGContextPlugin | scenegraph | Qt Quick | 大文字小文字を区別 |
QSqlDriverPlugin | sqldrivers | Qt SQL | 大文字小文字を区別 |
QIconEnginePlugin | iconengines | Qt SVG | 大文字小文字を区別しない |
QAccessiblePlugin | accessible | Qt Widgets | 大文字小文字を区別 |
QStylePlugin | styles | Qt 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: bool openJsonFile(); QTreeView *m_tree; QListWidget *m_toplevel = nullptr; QJsonDocument m_root; QPointer<QLineEdit> m_searchKey; };
クラス実装が.cpp
ファイルにあることを確認してください:
JsonViewer::JsonViewer() { connect(this, &AbstractViewer::uiInitialized, this, &JsonViewer::setupJsonUi); } void JsonViewer::init(QFile *file, QWidget *parent, QMainWindow *mainWindow) { AbstractViewer::init(file, new QTreeView(parent), mainWindow); m_tree = qobject_cast<QTreeView *>(widget()); }
さらに、プラグインを説明するメタデータを含むjsonファイル(jsonviewer.json
)が、ほとんどのプラグインに必要です。ドキュメント・ビューア・プラグインの場合は、単にビューア・プラグインの名前が含まれます。
{ "Keys": [ "jsonviewer" ] }
jsonファイルで提供する必要がある情報のタイプは、プラグインに依存します。ファイルに含める必要がある情報の詳細については、クラスのドキュメントを参照してください。
データベースドライバ、画像フォーマット、テキストコーデック、その他ほとんどのプラグインでは、明示的にオブジェクトを作成する必要はありません。Qtが必要に応じてそれらを見つけ、作成します。
プラグインクラスは、追加関数を実装する必要があるかもしれません。プラグインの種類ごとに再実装が必要な仮想関数の詳細については、クラスのドキュメントを参照してください。
ドキュメント・ビューア・デモでは、構造化されたファイルの内容を表示するプラグインの実装方法を示しています。そのため、各プラグインは以下の仮想関数を再実装しています。
- プラグインを識別する
- サポートしている 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 の機能を拡張するプラグインの種類に限定されません。
プラグインによってアプリケーションを拡張可能にするには、次のような手順が必要です:
- プラグインとやり取りするためのインターフェース(純粋な仮想関数のみを持つクラス)を定義する。
- Q_DECLARE_INTERFACE() マクロを使用して、Qt のメタオブジェクトシステムにインターフェイスを伝えます。
- アプリケーションでQPluginLoader を使ってプラグインをロードします。
- qobject_cast() を使って、プラグインが与えられたインターフェイスを実装しているかどうかをテストします。
プラグインを書くには、以下のステップを踏みます:
- QObject およびプラグインが提供したいインターフェースを継承したプラグインクラスを宣言する。
- Q_INTERFACES() マクロを使用して、Qt のメタオブジェクトシステムにインターフェースを伝えます。
- 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コマンドを呼び出す必要があります。
例えば、Linuxlibinput
プラグインはデフォルトではインポートされません。次のコマンドでインポートします:
qt_import_plugins(myapp INCLUDE Qt::QLibInputPlugin)
デフォルトの Qt Platform Adaptation プラグインの代わりに最小限の Platform Integration プラグインをリンクするには、次のようにします:
qt_import_plugins(myapp INCLUDE_BY_TYPE platforms Qt::MinimalIntegrationPlugin )
もう一つの典型的な使用例は、特定の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
静的プラグインの作成
以下の手順に従って、独自のスタティック・プラグインを作成することも可能です:
CMakeLists.txt
のqt_add_pluginコマンドにSTATIC
オプションを渡します。qmake プロジェクトの場合、プラグインの.pro
ファイルにCONFIG += static
を追加します。- アプリケーションでQ_IMPORT_PLUGIN() マクロを使用します。
- プラグインが qrc ファイルを同梱している場合は、アプリケーションでQ_INIT_RESOURCE() マクロを使用します。
CMakeLists.txt
または.pro
ファイルのLIBS
でtarget_link_libraries を使用して、アプリケーションとプラグイン・ライブラリをリンクします。
この方法の詳細については、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固有の処理が必要になる場合があります。
// 共有プラグインをロードする QDirpluginsDir=QDir(QApplication::applicationDirPath());#if defined(Q_OS_WINDOWS)pluginsDir.cd("app"_L1);#elif defined(Q_OS_DARWIN) if(pluginsDir.dirName()== "MacOS"_L1) { pluginsDir.cdUp(); pluginsDir.cdUp(); }#endif const autoentryList=pluginsDir.entryList(QDir::Files);for(constQString&fileName: entryList) { の場合 QPluginLoaderloader(pluginsDir.absoluteFilePath(fileName)); QObject*plugin =loader.instance();if(plugin) addViewer(plugin);#if 0 else qDebug() << loader.errorString(); #endif} }
プラグインのデプロイとデバッグ
プラグインのデプロイ」ドキュメントでは、アプリケーションとプラグインをデプロイするプロセスと、問題が発生したときのデバッグについて説明します。
QPluginLoader とQLibraryも参照してください 。
© 2025 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.