Spec-Zone.ru › Qt 6.1

Как создать плагины Qt

Qt предоставляет два API для создания плагинов:

  • Высокоуровневый API для написания расширений самого Qt: пользовательские драйверы баз данных, форматы изображений, кодеки текста, пользовательские стили и т.д.
  • Низкоуровневый API для расширения приложений Qt.

Например, если вы хотите написать подкласс пользовательского QStyle и хотите, чтобы приложения Qt динамически загружали его, вы бы использовали высокоуровневый API.

Поскольку высокоуровневый API построен поверх низкоуровневого API, некоторые проблемы общие для обоих.

Если вы хотите предоставить плагины для использования с Qt Designer, см. документацию модуля Qt Designer.

Темы:

Высокоуровневый 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 Platform Abstraction Нечувствителен к регистру
QPlatformIntegrationPlugin platforms Qt Platform Abstraction Нечувствителен к регистру
QPlatformThemePlugin platformthemes Qt Platform Abstraction Нечувствителен к регистру
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 Нечувствителен к регистру

Если у вас есть новый класс стиля под названием MyStyle, который вы хотите сделать доступным в виде плагина, класс необходимо определить следующим образом (mystyleplugin.h):

class MyStylePlugin : public QStylePlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "mystyleplugin.json")
public:
    QStyle *create(const QString &key);
};

Убедитесь, что реализация класса находится в файле .cpp:

#include "mystyleplugin.h"

QStyle *MyStylePlugin::create(const QString &key)
{
    if (key.toLower() == "mystyle")
        return new MyStyle;
    return 0;
}

(Обратите внимание, что QStylePlugin нечувствителен к регистру, и в нашей реализации create() используется строчная версия ключа; большинство других плагинов чувствительны к регистру.)

Кроме того, для большинства плагинов требуется файл json (mystyleplugin.json), содержащий метаданные, описывающие плагин. Для плагинов стиля он просто содержит список стилей, которые может создать плагин:

{ "Keys": [ "mystyleplugin" ] }

Тип информации, который необходимо предоставить в файле json, зависит от плагина. Пожалуйста, см. документацию класса для получения подробной информации о необходимой информации.

Для драйверов баз данных, форматов изображений, кодировок текста и большинства других типов плагинов явного создания объектов не требуется. Qt найдет и создаст их по мере необходимости. Стиль является исключением, так как вы можете явно установить стиль в коде. Для применения стиля используйте код подобный этому:

QApplication::setStyle(QStyleFactory::create("MyStyle"));

Некоторые классы плагинов требуют реализации дополнительных функций. См. документацию по классу для получения подробностей о виртуальных функциях, которые необходимо переопределить для каждого типа плагина.

В примере Style Plugin Example показано, как реализовать плагин, расширяющий базовый класс QStylePlugin.

Низкоуровневый 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().
  4. Компоновка плагина с помощью соответствующего файла .pro.

Например, вот определение класса интерфейса:

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

    virtual QStringList filters() const = 0;
    virtual QImage filterImage(const QString &filter, const QImage &image,
                               QWidget *parent) = 0;
};

Вот определение класса плагина, который реализует этот интерфейс:

#include <QObject>
#include <QtPlugin>
#include <QStringList>
#include <QImage>

#include <plugandpaint/interfaces.h>

class ExtraFiltersPlugin : public QObject, public FilterInterface
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.PlugAndPaint.FilterInterface" FILE "extrafilters.json")
    Q_INTERFACES(FilterInterface)

public:
    QStringList filters() const;
    QImage filterImage(const QString &filter, const QImage &image,
                       QWidget *parent);
};

Документация примера Plug & Paint подробно объясняет этот процесс. Также см. Создание пользовательских виджетов для Qt Designer для получения информации о проблемах, специфичных для Qt Designer. Вы также можете посмотреть пример Echo Plugin Example, который является более тривиальным примером реализации плагина, расширяющего приложения Qt. Обратите внимание, что QCoreApplication должен быть инициализирован до загрузки плагинов.

Поиск плагинов

Приложения Qt автоматически знают, какие плагины доступны, потому что плагины хранятся в стандартных подкаталогах плагинов. Благодаря этому приложениям не нужен никакой код для поиска и загрузки плагинов, поскольку Qt обрабатывает их автоматически.

Во время разработки каталог для плагинов находится в QTDIR/plugins (где QTDIR - каталог установки Qt), причем каждый тип плагина находится в подкаталоге для этого типа, например, styles. Если вы хотите, чтобы ваши приложения использовали плагины, и вы не хотите использовать стандартный путь для плагинов, запустите процесс установки, чтобы определить путь, который вы хотите использовать для плагинов, и сохраните этот путь, например, используя QSettings, чтобы приложение могло его прочитать во время работы. Затем приложение может вызвать QCoreApplication::addLibraryPath() с этим путем, и ваши плагины будут доступны приложению. Обратите внимание, что конечная часть пути (например, styles) не может быть изменена.

Если вы хотите, чтобы плагин был загружаемым, один из подходов заключается в создании подкаталога в приложении и размещении плагина в этом каталоге. Если вы распространяете какие-либо плагины, которые поставляются с Qt (те, которые находятся в каталоге plugins), вы должны скопировать подкаталог под plugins, где находится плагин, в корневую папку вашего приложения (т.е., не включайте каталог plugins).

Для получения более подробной информации о развертывании см. документацию Развертывание приложений Qt и Развертывание плагинов.

Статические плагины

Обычный и самый гибкий способ включения плагина с приложением — это скомпилировать его в динамическую библиотеку, которая поставляется отдельно и обнаруживается и загружается во время выполнения.

Плагины могут быть статически связаны с вашим приложением. Если вы строили статическую версию Qt, это единственный вариант включения предопределенных плагинов Qt. Использование статических плагинов делает развертывание менее подверженным ошибкам, но имеет недостаток, что никакая функциональность от плагинов не может быть добавлена без полной пересборки и перераспределения приложения.

Для статической компоновки плагинов необходимо добавить необходимые плагины к вашей сборке, используя QTPLUGIN.

В файле .pro вашего приложения необходима следующая запись:

QTPLUGIN     += qjpeg \
                qgif \
                qkrcodecs

qmake автоматически добавляет плагины в QTPLUGIN, которые обычно необходимы для используемых модулей Qt (см. QT), в то время как более специализированные плагины необходимо добавлять вручную. По умолчанию список автоматически добавляемых плагинов можно переопределить по типу. Например, чтобы связать минимальный плагин вместо плагина адаптации платформы Qt по умолчанию, используйте:

QTPLUGIN.platforms = qminimal

Если вы не хотите связывать ни плагин платформы по умолчанию, ни минимальный плагин QPA автоматически, используйте:

QTPLUGIN.platforms = -

Значения по умолчанию настраиваются для оптимального опыта использования «из коробки», но могут излишне увеличивать размер приложения. Рекомендуется проверить командную строку компоновщика, сгенерированную qmake, и исключить ненужные плагины.

Подробности статической компоновки плагинов

Чтобы статические плагины фактически подключались и инициализировались, в коде приложения также необходимы макросы Q_IMPORT_PLUGIN(), но они автоматически генерируются qmake и добавляются в ваш проект приложения.

Если вы не хотите, чтобы все плагины, добавленные в QTPLUGIN, автоматически подключались, удалите import_plugins из переменной CONFIG:

CONFIG -= import_plugins

Создание статических плагинов

Также можно создать собственные статические плагины, выполнив следующие шаги:

  1. Добавьте CONFIG += static в файл .pro вашего плагина.
  2. Используйте макрос Q_IMPORT_PLUGIN() в своем приложении.
  3. Используйте макрос Q_INIT_RESOURCE() в приложении, если плагин содержит файлы qrc.
  4. Свяжите приложение с вашей библиотекой плагина, используя LIBS в файле .pro.

См. пример Plug & Paint и связанный с ним плагин Basic Tools для получения подробностей.

Примечание: Если вы не используете qmake для построения вашего плагина, вам необходимо убедиться, что препроцессорский макрос QT_STATICPLUGIN определён.

Развёртывание и отладка плагинов

Документ Развёртывание плагинов описывает процесс развёртывания плагинов с приложениями и отладки при возникновении проблем.

См. также QPluginLoader, QLibrary и Пример Plug & Paint.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.1/plugins-howto.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API