Comment créer des plugins Qt
Qt fournit deux API pour créer des plugins :
- Une API de haut niveau pour écrire des extensions à Qt lui-même, comme des pilotes de base de données personnalisés, des formats d'image, des codecs de texte et des styles.
- Une API de bas niveau pour étendre les applications Qt.
Par exemple, si vous souhaitez écrire une sous-classe QStyle personnalisée et faire en sorte que les applications Qt la chargent dynamiquement, vous utiliserez l'API de haut niveau.
Étant donné que l'API de niveau supérieur est construite sur l'API de niveau inférieur, certains problèmes sont communs aux deux.
Si vous souhaitez fournir des plugins à utiliser avec Qt Widgets Designer, voir Création de plugins de widgets personnalisés.
L'API de haut niveau : Écrire des extensions Qt
Pour écrire un plugin qui étend Qt lui-même, il suffit de sous-classer la classe de base du plugin approprié, d'implémenter quelques fonctions et d'ajouter une macro.
Il existe plusieurs classes de base de plugins. Les plugins dérivés sont stockés par défaut dans des sous-répertoires du répertoire standard des plugins. Qt ne trouvera pas les plugins s'ils ne sont pas stockés dans le répertoire approprié.
Le tableau suivant résume les classes de base des plugins. Certaines de ces classes sont privées et ne sont donc pas documentées. Vous pouvez les utiliser, mais il n'y a aucune promesse de compatibilité avec les versions ultérieures de Qt.
| Classe de base | Nom du répertoire | Module Qt | Clé Sensibilité à la casse |
|---|---|---|---|
| QAccessibleBridgePlugin | accessiblebridge | Qt GUI | Sensible à la casse |
| QImageIOPlugin | imageformats | Qt GUI | Sensible à la casse |
| QPictureFormatPlugin (obsolète) | pictureformats | Qt GUI | Sensible à la casse |
| QBearerEnginePlugin (obsolète) | bearer | Qt Network | Sensible à la casse |
| QPlatformInputContextPlugin | platforminputcontexts | Abstraction de la plate-forme Qt | Insensible à la casse |
| QPlatformIntegrationPlugin | platforms | Abstraction de la plate-forme Qt | Insensible à la casse |
| QPlatformThemePlugin | platformthemes | Abstraction de la plate-forme Qt | Insensible à la casse |
| QPlatformPrinterSupportPlugin | printsupport | Qt Print Support | Insensible à la casse |
| QSGContextPlugin | scenegraph | Qt Quick | Sensible à la casse |
| QSqlDriverPlugin | sqldrivers | Qt SQL | Insensible à la casse |
| QIconEnginePlugin | iconengines | Qt SVG | Insensible à la casse |
| QAccessiblePlugin | accessible | Qt Widgets | Insensible à la casse |
| QStylePlugin | styles | Qt Widgets | Insensible à la casse |
Si vous avez une nouvelle classe de visualisation de documents appelée JsonViewer que vous voulez rendre disponible en tant que plugin, la classe doit être définie comme suit (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; QMenu *m_jsonMenu = nullptr; QToolBar *m_jsonToolBar = nullptr; QAction *m_expandAllAction = nullptr; QAction *m_collapseAllAction = nullptr; };
Assurez-vous que l'implémentation de la classe se trouve dans un fichier .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); setTranslationBaseName("jsonviewer"_L1); m_tree = qobject_cast<QTreeView *>(widget()); }
En outre, un fichier json (jsonviewer.json) contenant des métadonnées décrivant le plugin est nécessaire pour la plupart des plugins. Pour les plugins de visualisation de documents, il contient simplement le nom du plugin de visualisation.
{ "Keys": [ "jsonviewer" ] }Le type d'informations à fournir dans le fichier json dépend du plugin. Voir la documentation de la classe pour plus de détails sur les informations qui doivent être contenues dans le fichier.
Pour les pilotes de base de données, les formats d'image, les codecs de texte et la plupart des autres types de plugins, aucune création explicite d'objet n'est nécessaire. Qt les trouvera et les créera si nécessaire.
Les classes de plugins peuvent nécessiter l'implémentation de fonctions supplémentaires. Voir la documentation de la classe pour plus de détails sur les fonctions virtuelles qui doivent être réimplémentées pour chaque type de plugin.
La démo Document Viewer montre comment implémenter un plugin qui affiche le contenu structuré d'un fichier. Chaque plugin réimplémente donc des fonctions virtuelles, qui
- identifient le greffon
- renvoient les types MIME qu'il prend en charge
- indiquent s'il y a du contenu à afficher et
- comment le contenu est présenté
QString viewerName() const override { return QLatin1StringView(staticMetaObject.className()); }; QStringList supportedMimeTypes() const override; bool hasContent() const override; bool supportsOverview() const override { return true; }
L'API de bas niveau : Extension des applications Qt
En plus de Qt lui-même, les applications Qt peuvent être étendues par des plugins. Pour ce faire, l'application doit détecter et charger les plugins à l'aide de QPluginLoader. Dans ce contexte, les plugins peuvent fournir des fonctionnalités arbitraires et ne sont pas limités aux pilotes de base de données, aux formats d'image, aux codecs de texte, aux styles et à d'autres types de plugins qui étendent les fonctionnalités de Qt.
Rendre une application extensible par le biais de plugins implique les étapes suivantes :
- Définir un ensemble d'interfaces (classes ne comportant que des fonctions virtuelles pures) utilisées pour communiquer avec les modules d'extension.
- Utiliser la macro Q_DECLARE_INTERFACE() pour informer le système de méta-objets de Qt de l'existence de l'interface.
- Utilisez QPluginLoader dans l'application pour charger les modules d'extension.
- Utilisez qobject_cast() pour tester si un plugin implémente une interface donnée.
L'écriture d'un plugin implique les étapes suivantes :
- Déclarez une classe de plugin qui hérite de QObject et des interfaces que le plugin veut fournir.
- Utiliser la macro Q_INTERFACES() pour indiquer les interfaces au système de méta-objets de Qt.
- Exporter le plugin en utilisant la macro Q_PLUGIN_METADATA().
Par exemple, voici la définition d'une classe d'interface :
class ViewerInterface : public AbstractViewer { public: virtual ~ViewerInterface() = default; };
Voici la déclaration de l'interface :
#define ViewerInterface_iid "org.qt-project.Qt.Examples.DocumentViewer.ViewerInterface/1.0" Q_DECLARE_INTERFACE(ViewerInterface, ViewerInterface_iid)
Voir aussi Créer des widgets personnalisés pour Qt Widgets Designer pour des informations sur les problèmes spécifiques à Qt Widgets Designer. Voir l'exemple de plugin de backend de calendrier pour un exemple d'utilisation d'un plugin afin d'ajouter la prise en charge d'un système de calendrier personnalisé.
Localisation des plugins
Les applications Qt savent automatiquement quels plugins sont disponibles, car les plugins sont stockés dans les sous-répertoires de plugins standard. De ce fait, les applications n'ont pas besoin de code pour trouver et charger les plugins, puisque Qt s'en charge automatiquement.
Pendant le développement, le répertoire des plugins est QTDIR/plugins (où QTDIR est le répertoire où Qt est installé), avec chaque type de plugin dans un sous-répertoire pour ce type, par exemple, styles. Si vous voulez que vos applications utilisent des plugins et que vous ne voulez pas utiliser le chemin standard des plugins, demandez à votre processus d'installation de déterminer le chemin que vous voulez utiliser pour les plugins, et enregistrez le chemin, par exemple, en utilisant QSettings, pour que l'application le lise lorsqu'elle s'exécute. L'application peut alors appeler QCoreApplication::addLibraryPath() avec ce chemin et vos plugins seront disponibles pour l'application. Notez que la dernière partie du chemin (par exemple, styles) ne peut pas être modifiée.
Si vous souhaitez que le plugin puisse être chargé, une approche consiste à créer un sous-répertoire sous l'application et à placer le plugin dans ce répertoire. Si vous distribuez l'un des plugins fournis avec Qt XML (ceux qui se trouvent dans le répertoire plugins ), vous devez copier le sous-répertoire sous plugins où se trouve le plugin dans le dossier racine de votre application (c'est-à-dire que vous ne devez pas inclure le répertoire plugins ).
Pour plus d'informations sur le déploiement, voir la documentation Déploiement des applications Qt et Déploiement des plugins.
Plugins statiques
La manière la plus normale et la plus souple d'inclure un plugin dans une application est de le compiler dans une bibliothèque dynamique qui est livrée séparément, puis détectée et chargée au moment de l'exécution.
Les plugins peuvent être liés statiquement à votre application. Si vous construisez la version statique de Qt, c'est la seule option pour inclure les plugins prédéfinis de Qt. L'utilisation de plugins statiques rend le déploiement moins sujet aux erreurs, mais présente l'inconvénient qu'aucune fonctionnalité des plugins ne peut être ajoutée sans une reconstruction et une redistribution complètes de l'application.
CMake et qmake ajoutent automatiquement les plugins généralement nécessaires aux modules Qt utilisés, tandis que les plugins plus spécialisés doivent être ajoutés manuellement. La liste par défaut des plugins ajoutés automatiquement peut être modifiée pour chaque type.
Les valeurs par défaut sont conçues pour offrir une expérience optimale dès la sortie de la boîte, mais peuvent gonfler inutilement l'application. Il est recommandé d'inspecter la ligne de commande de l'éditeur de liens et d'éliminer les plugins inutiles.
Pour que les greffons statiques soient effectivement liés et instanciés, les macros Q_IMPORT_PLUGIN() sont également nécessaires dans le code de l'application, mais elles sont automatiquement générées par le système de construction et ajoutées à votre projet d'application.
Importation de plugins statiques dans CMake
Pour lier statiquement des plugins dans un projet CMake, vous devez appeler la commande qt_import_plugins.
Par exemple, le plugin Linux libinput n'est pas importé par défaut. La commande suivante l'importe :
qt_import_plugins(myapp INCLUDE Qt::QLibInputPlugin)
Pour lier le plugin d'intégration de plateforme minimale au lieu du plugin d'adaptation de plateforme Qt par défaut, utilisez :
qt_import_plugins(myapp
INCLUDE_BY_TYPE platforms Qt::MinimalIntegrationPlugin
)Un autre cas d'utilisation typique consiste à ne lier qu'un certain ensemble de plugins imageformats:
qt_import_plugins(myapp
INCLUDE_BY_TYPE imageformats Qt::QJpegPlugin Qt::QGifPlugin
)Si vous voulez empêcher la liaison de tout plugin imageformats, utilisez :
qt_import_plugins(myapp
EXCLUDE_BY_TYPE imageformats
)Si vous souhaitez désactiver l'ajout d'un plugin par défaut, utilisez l'option NO_DEFAULT de qt_import_plugins.
Importer des plugins statiques dans qmake
Dans un projet qmake, vous devez ajouter les plugins nécessaires à votre compilation en utilisant QTPLUGIN:
QTPLUGIN += qlibinputplugin
Par exemple, pour lier le plugin minimal au lieu du plugin d'adaptation à la plateforme Qt par défaut, utilisez :
QTPLUGIN.platforms = qminimal
Si vous souhaitez que ni le plugin QPA par défaut, ni le plugin QPA minimal ne soient liés automatiquement, utilisez :
QTPLUGIN.platforms = -
Si vous ne voulez pas que tous les plugins ajoutés à QTPLUGIN soient automatiquement liés, supprimez import_plugins de la variable CONFIG:
CONFIG -= import_plugins
Création de plugins statiques
Il est également possible de créer vos propres plugins statiques en suivant les étapes suivantes :
- Passez l'option
STATICà la commande qt_add_plugin dans votreCMakeLists.txt. Pour un projet qmake, ajoutezCONFIG += staticau fichier.prode votre plugin. - Utilisez la macro Q_IMPORT_PLUGIN() dans votre application.
- Utilisez la macro Q_INIT_RESOURCE() dans votre application si le plugin fournit des fichiers qrc.
- Liez votre application à la bibliothèque de votre plugin en utilisant target_link_libraries dans votre fichier
CMakeLists.txtouLIBSdans votre fichier.pro.
Voir l'exemple Plug & Paint et le plugin Basic Tools associé pour plus de détails sur la manière de procéder.
Note : Si vous n'utilisez pas CMake ou qmake pour construire votre plugin, vous devez vous assurer que la macro du préprocesseur QT_STATICPLUGIN est définie.
Chargement des plugins
Les types de greffons (statiques ou partagés) et les systèmes d'exploitation nécessitent des approches spécifiques pour localiser et charger les greffons. Il est utile d'implémenter une abstraction pour le chargement des plugins.
void ViewerFactory::loadViewerPlugins() { if (!m_viewers.isEmpty()) return;
QPluginLoader::staticInstances() renvoie une adresse QObjectList avec un pointeur sur chaque plugin lié statiquement.
// Load static plugins const QObjectList &staticPlugins = QPluginLoader::staticInstances(); for (auto *plugin : staticPlugins) addViewer(plugin);
Les plugins partagés résident dans leurs répertoires de déploiement, ce qui peut nécessiter une gestion spécifique au système d'exploitation.
// Chargement des plugins partagés QDir pluginsDir = QDir(QApplication::applicationDirPath()) ;#if defined(Q_OS_DARWIN) if (pluginsDir.exists("../PlugIns"_L1)) { // construction installéepluginsDir.cd("../PlugIns"_L1) ; } else { pluginsDir.cd("../../../../plugins"_L1) ; // version non installée}#elif defined(Q_OS_WIN) if (pluginsDir.exists("plugins"_L1)) { // version non installée pluginsDir.cd("plugins"_L1) ; } else { pluginsDir.cd("../plugins"_L1) ; // version installée}#elsepluginsDir.cd("../plugins"_L1) ; // version installée et non installée#endif // qDebug("Loading plugins from %s...", qUtf8Printable(pluginsDir.path())) ; const auto entryList = pluginsDir.entryList(QDir::Files) ; for(const QString &fileName: entryList) { QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)) ; QObject *plugin = loader.instance() ; if (plugin) addViewer(plugin) ;#if 0 else qDebug() << loader.errorString(); #endif} }
Déploiement et débogage des plugins
Le document Déploiement des plugins couvre le processus de déploiement des plugins avec les applications et leur débogage en cas de problème.
Voir également QPluginLoader et 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.