Cómo crear plugins de Qt
Qt proporciona dos APIs para crear plugins:
- Una API de alto nivel para escribir extensiones del propio Qt, como controladores personalizados de bases de datos, formatos de imagen, códecs de texto y estilos.
- Una API de bajo nivel para extender las aplicaciones Qt.
Por ejemplo, si quieres escribir una subclase personalizada de QStyle y hacer que las aplicaciones Qt la carguen dinámicamente, utilizarías la API de alto nivel.
Dado que la API de alto nivel se construye sobre la API de bajo nivel, algunos problemas son comunes a ambas.
Si desea proporcionar plugins para su uso con Qt Widgets Designer, consulte Creación de plugins de widgets personalizados.
La API de alto nivel: Escribiendo Extensiones Qt
Escribir un plugin que extienda el propio Qt se consigue subclasificando la clase base del plugin apropiado, implementando algunas funciones y añadiendo una macro.
Existen varias clases base de plugins. Los plugins derivados se almacenan por defecto en subdirectorios del directorio estándar de plugins. Qt no encontrará los plugins si no están almacenados en el directorio apropiado.
La siguiente tabla resume las clases base de los plugins. Algunas de las clases son privadas, y por lo tanto no están documentadas. Puedes usarlas, pero no hay promesa de compatibilidad con versiones posteriores de Qt.
| Clase Base | Nombre del directorio | Módulo Qt | Clave Sensibilidad a mayúsculas y minúsculas |
|---|---|---|---|
| QAccessibleBridgePlugin | accessiblebridge | Qt GUI | Sensible a mayúsculas y minúsculas |
| QImageIOPlugin | imageformats | Qt GUI | Sensible a mayúsculas y minúsculas |
| QPictureFormatPlugin (obsoleto) | pictureformats | Qt GUI | Sensible a mayúsculas y minúsculas |
| QBearerEnginePlugin | bearer | Qt Network | Sensible a mayúsculas y minúsculas |
| QPlatformInputContextPlugin | platforminputcontexts | Abstracción de plataforma Qt | No distingue mayúsculas de minúsculas |
| QPlatformIntegrationPlugin | platforms | Abstracción de plataforma Qt | Insensible a mayúsculas y minúsculas |
| QPlatformThemePlugin | platformthemes | Abstracción de la plataforma Qt | Insensible a mayúsculas y minúsculas |
| QPlatformPrinterSupportPlugin | printsupport | Qt Print Support | Insensible a mayúsculas y minúsculas |
| QSGContextPlugin | scenegraph | Qt Quick | Sensible a mayúsculas y minúsculas |
| QSqlDriverPlugin | sqldrivers | Qt SQL | Sensible a mayúsculas y minúsculas |
| QIconEnginePlugin | iconengines | Qt SVG | Insensible a mayúsculas y minúsculas |
| QAccessiblePlugin | accessible | Qt Widgets | Sensible a mayúsculas y minúsculas |
| QStylePlugin | styles | Qt Widgets | No distingue mayúsculas de minúsculas |
Si tienes una nueva clase de visor de documentos llamada JsonViewer que quieres hacer disponible como plugin, la clase necesita ser definida como sigue (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; };
Asegúrese de que la implementación de la clase se encuentra en un archivo .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()); }
Además, para la mayoría de los plugins se requiere un archivo json (jsonviewer.json) que contenga metadatos que describan el plugin. En el caso de los complementos de visor de documentos, simplemente contiene el nombre del complemento de visor.
{ "Keys": [ "jsonviewer" ] }El tipo de información que debe proporcionarse en el archivo json depende del complemento. Consulte la documentación de la clase para obtener más detalles sobre la información que debe contener el archivo.
Para los controladores de bases de datos, formatos de imagen, codecs de texto y la mayoría de los otros tipos de plugins, no se requiere la creación explícita de objetos. Qt los encontrará y creará según sea necesario.
Las clases de complementos pueden requerir la implementación de funciones adicionales. Consulte la documentación de la clase para más detalles sobre las funciones virtuales que deben ser reimplementadas para cada tipo de plugin.
La demostración del visor de documentos muestra cómo implementar un complemento que muestra el contenido estructurado de un archivo. Por lo tanto, cada plugin reimplementa funciones virtuales, que
- identifican el complemento
- devuelven los tipos MIME que soporta
- informan de si hay contenido que mostrar y
- cómo se presentan los contenidos
QString viewerName() const override { return QLatin1StringView(staticMetaObject.className()); }; QStringList supportedMimeTypes() const override; bool hasContent() const override; bool supportsOverview() const override { return true; }
La API de bajo nivel: Ampliación de aplicaciones Qt
Además del propio Qt, las aplicaciones Qt pueden ampliarse mediante plugins. Esto requiere que la aplicación detecte y cargue plugins usando QPluginLoader. En ese contexto, los plugins pueden proporcionar funcionalidad arbitraria y no se limitan a controladores de bases de datos, formatos de imagen, códecs de texto, estilos y otros tipos de plugins que extienden la funcionalidad de Qt.
Hacer una aplicación extensible mediante plugins implica los siguientes pasos:
- Definir un conjunto de interfaces (clases con sólo funciones virtuales puras) utilizadas para hablar con los plugins.
- Utilizar la macro Q_DECLARE_INTERFACE() para informar al sistema de meta-objetos de Qt sobre la interfaz.
- Usa QPluginLoader en la aplicación para cargar los plugins.
- Utilice qobject_cast() para comprobar si un plugin implementa una interfaz dada.
Escribir un plugin implica estos pasos:
- Declarar una clase plugin que herede de QObject y de las interfaces que el plugin quiera proporcionar.
- Utilizar la macro Q_INTERFACES() para informar al sistema de meta-objetos de Qt sobre las interfaces.
- Exportar el plugin usando la macro Q_PLUGIN_METADATA().
Por ejemplo, aquí está la definición de una clase de interfaz:
class ViewerInterface : public AbstractViewer { public: virtual ~ViewerInterface() = default; };
Aquí está la declaración de la interfaz:
#define ViewerInterface_iid "org.qt-project.Qt.Examples.DocumentViewer.ViewerInterface/1.0" Q_DECLARE_INTERFACE(ViewerInterface, ViewerInterface_iid)
Consulte también Creación de widgets personalizados para Qt Widgets Designer para obtener información sobre cuestiones específicas de Qt Widgets Designer. Consulte el ejemplo de plugin de backend de calendario para ver un ejemplo de uso de un plugin para añadir compatibilidad con un sistema de calendario personalizado.
Localización de plugins
Las aplicaciones Qt saben automáticamente qué plugins están disponibles, porque los plugins se almacenan en los subdirectorios estándar de plugins. Debido a esto, las aplicaciones no requieren ningún código para encontrar y cargar plugins, ya que Qt los maneja automáticamente.
Durante el desarrollo, el directorio para los plugins es QTDIR/plugins (donde QTDIR es el directorio donde Qt está instalado), con cada tipo de plugin en un subdirectorio para ese tipo, por ejemplo, styles. Si quieres que tus aplicaciones usen plugins y no quieres usar la ruta estándar de plugins, haz que tu proceso de instalación determine la ruta que quieres usar para los plugins, y guarda la ruta, por ejemplo, usando QSettings, para que la aplicación la lea cuando se ejecute. La aplicación puede entonces llamar a QCoreApplication::addLibraryPath() con esta ruta y tus plugins estarán disponibles para la aplicación. Tenga en cuenta que la parte final de la ruta (por ejemplo, styles) no se puede cambiar.
Si quieres que el plugin sea cargable, un enfoque es crear un subdirectorio bajo la aplicación, y colocar el plugin en ese directorio. Si distribuyes alguno de los plugins que vienen con Qt (los que se encuentran en el directorio plugins ), debes copiar el subdirectorio bajo plugins donde se encuentra el plugin a la carpeta raíz de tus aplicaciones (es decir, no incluyas el directorio plugins ).
Para más información sobre el despliegue, consulte la documentación Despliegue de aplicaciones Qt y Despliegue de plugins.
Plugins estáticos
La forma normal y más flexible de incluir un plugin con una aplicación es compilarlo en una librería dinámica que se envía por separado, y se detecta y carga en tiempo de ejecución.
Los plugins pueden enlazarse estáticamente en tu aplicación. Si construyes la versión estática de Qt, esta es la única opción para incluir los plugins predefinidos de Qt. Usar plugins estáticos hace que el despliegue sea menos propenso a errores, pero tiene la desventaja de que no se puede añadir ninguna funcionalidad de los plugins sin una completa reconstrucción y redistribución de la aplicación.
CMake y qmake añaden automáticamente los plugins que suelen necesitar los módulos Qt que se utilizan, mientras que los plugins más especializados deben añadirse manualmente. La lista predeterminada de plugins añadidos automáticamente se puede anular por tipo.
Los valores por defecto están orientados a una experiencia óptima, pero pueden sobrecargar innecesariamente la aplicación. Se recomienda inspeccionar la línea de comandos del enlazador y eliminar los plugins innecesarios.
Para que los plugins estáticos sean enlazados e instanciados, también se necesitan las macros Q_IMPORT_PLUGIN() en el código de la aplicación, pero éstas son generadas automáticamente por el sistema de compilación y añadidas al proyecto de la aplicación.
Importación de plugins estáticos en CMake
Para vincular estáticamente plugins en un proyecto CMake, es necesario llamar al comando qt_import_plugins.
Por ejemplo, el plugin de Linux libinput no se importa por defecto. El siguiente comando lo importa:
qt_import_plugins(myapp INCLUDE Qt::QLibInputPlugin)
Para vincular el plugin de integración de plataforma mínima en lugar del plugin de adaptación de plataforma Qt por defecto, utilice:
qt_import_plugins(myapp
INCLUDE_BY_TYPE platforms Qt::MinimalIntegrationPlugin
)Otro caso de uso típico es vincular sólo un determinado conjunto de plugins de imageformats:
qt_import_plugins(myapp
INCLUDE_BY_TYPE imageformats Qt::QJpegPlugin Qt::QGifPlugin
)Si desea evitar la vinculación de cualquier plugin imageformats, utilice:
qt_import_plugins(myapp
EXCLUDE_BY_TYPE imageformats
)Si desea desactivar la adición de cualquier plugin por defecto, utilice la opción NO_DEFAULT de qt_import_plugins.
Importando plugins estáticos en qmake
En un proyecto qmake, necesitas agregar los plugins requeridos a tu compilación usando QTPLUGIN:
QTPLUGIN += qlibinputplugin
Por ejemplo, para vincular el plugin mínimo en lugar del plugin de adaptación de la plataforma Qt por defecto, utilice:
QTPLUGIN.platforms = qminimal
Si no desea que se vinculen automáticamente ni el plugin QPA predeterminado ni el mínimo, utilice:
QTPLUGIN.platforms = -
Si no desea que todos los plugins añadidos a QTPLUGIN se vinculen automáticamente, elimine import_plugins de la variable CONFIG:
CONFIG -= import_plugins
Creación de plugins estáticos
También es posible crear tus propios plugins estáticos siguiendo estos pasos:
- Pase la opción
STATICal comando qt_add_plugin en suCMakeLists.txt. Para un proyecto qmake, añadeCONFIG += statical archivo.prode tu plugin. - Utiliza la macro Q_IMPORT_PLUGIN() en tu aplicación.
- Utiliza la macro Q_INIT_RESOURCE() en tu aplicación si el plugin incluye archivos qrc.
- Enlaza tu aplicación con la librería de tu plugin usando target_link_libraries en tu archivo
CMakeLists.txtoLIBSen tu archivo.pro.
Vea el ejemplo Plug & Paint y el plugin asociado Basic Tools para más detalles sobre cómo hacer esto.
Nota: Si no estás usando CMake o qmake para construir tu plugin, necesitas asegurarte de que la macro del preprocesador QT_STATICPLUGIN está definida.
Carga de plugins
Los tipos de plugins (estáticos o compartidos) y los sistemas operativos requieren enfoques específicos para localizar y cargar plugins. Es útil implementar una abstracción para cargar plugins.
void ViewerFactory::loadViewerPlugins() { if (!m_viewers.isEmpty()) return;
QPluginLoader::staticInstances() devuelve un QObjectList con un puntero a cada plugin enlazado estáticamente
// Load static plugins const QObjectList &staticPlugins = QPluginLoader::staticInstances(); for (auto *plugin : staticPlugins) addViewer(plugin);
Los plugins compartidos residen en sus directorios de despliegue, lo que puede requerir un manejo específico del sistema operativo.
// Cargar plugins compartidos QDir pluginsDir = QDir(QApplication::applicationDirPath());#if defined(Q_OS_DARWIN) if (pluginsDir.exists("../PlugIns"_L1)) { // compilación instaladapluginsDir.cd("../PlugIns"_L1); } else { pluginsDir.cd("../../../plugins"_L1); // compilación no instalada}#elif defined(Q_OS_WIN) if (pluginsDir.exists("plugins"_L1)) { // compilación no instaladapluginsDir.cd("plugins"_L1); } else { pluginsDir.cd("../plugins"_L1); // compilación instalada}#elsepluginsDir.cd("../plugins"_L1); // compilación instalada y no instalada#endif // qDebug("Cargando plugins desde %s...", qUtf8Printable(pluginsDir.path())); const auto entryList = pluginsDir.entryList(QDir::Archivos); 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} }
Despliegue y depuración de plugins
El documento Despliegue de Plugins cubre el proceso de despliegue de plugins con aplicaciones y su depuración cuando surgen problemas.
Véase también QPluginLoader y 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.