Auf dieser Seite

So erstellen Sie Qt-Plugins

Qt bietet zwei APIs zum Erstellen von Plugins:

  • Eine High-Level-API zum Schreiben von Erweiterungen für Qt selbst, wie z. B. benutzerdefinierte Datenbanktreiber, Bildformate, Text-Codecs und Stile.
  • Eine Low-Level-API zur Erweiterung von Qt-Anwendungen.

Wenn Sie beispielsweise eine benutzerdefinierte Unterklasse von ` QStyle ` schreiben und möchten, dass Qt-Anwendungen diese dynamisch laden, würden Sie die hochrangige API verwenden.

Da die hochrangige API auf der niedrigrangigen API aufbaut, treten einige Probleme bei beiden auf.

Wenn Sie Plugins für die Verwendung mit dem „ Qt Widgets Designer“ bereitstellen möchten, lesen Sie den Abschnitt „Erstellen benutzerdefinierter Widget-Plugins“.

Die High-Level-API: Qt-Erweiterungen schreiben

Um ein Plugin zu schreiben, das Qt selbst erweitert, müssen Sie eine Unterklasse der entsprechenden Plugin-Basisklasse erstellen, einige Funktionen implementieren und ein Makro hinzufügen.

Es gibt mehrere Plugin-Basisklassen. Abgeleitete Plugins werden standardmäßig in Unterverzeichnissen des Standard-Plugin-Verzeichnisses gespeichert. Qt findet Plugins nicht, wenn sie nicht im entsprechenden Verzeichnis gespeichert sind.

Die folgende Tabelle fasst die Plugin-Basisklassen zusammen. Einige der Klassen sind privat und daher nicht dokumentiert. Sie können sie verwenden, es gibt jedoch keine Kompatibilitätsgarantie für spätere Qt-Versionen.

BasisklasseVerzeichnisnameQt-ModulGroß-/Kleinschreibung beachten
QAccessibleBridgePluginaccessiblebridgeQt GUIGroß-/Kleinschreibung beachten
QImageIOPluginimageformatsQt GUIGroß-/Kleinschreibung beachten
QPictureFormatPlugin (veraltet)pictureformatsQt GUIGroß-/Kleinschreibung beachten
QBearerEnginePluginbearerQt NetworkGroß-/Kleinschreibung beachten
QPlatformInputContextPluginplatforminputcontextsQt-PlattformabstraktionGroß-/Kleinschreibung wird nicht berücksichtigt
QPlatformIntegrationPluginplatformsQt-PlattformabstraktionGroß-/Kleinschreibung wird nicht berücksichtigt
QPlatformThemePluginplatformthemesQt-PlattformabstraktionGroß-/Kleinschreibung wird nicht berücksichtigt
QPlatformPrinterSupportPluginprintsupportQt Print SupportGroß-/Kleinschreibung wird nicht berücksichtigt
QSGContextPluginscenegraphQt QuickGroß-/Kleinschreibung beachten
QSqlDriverPluginsqldriversQt SQLGroß-/Kleinschreibung beachten
QIconEnginePluginiconenginesQt SVGGroß-/Kleinschreibung wird nicht berücksichtigt
QAccessiblePluginaccessibleQt WidgetsGroß-/Kleinschreibung beachten
QStylePluginstylesQt WidgetsGroß-/Kleinschreibung wird nicht berücksichtigt

Wenn Sie eine neue Dokumentenbetrachter-Klasse namens „ JsonViewer “ haben, die Sie als Plugin zur Verfügung stellen möchten, muss die Klasse wie folgt definiert werden (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;
};

Stellen Sie sicher, dass sich die Klassenimplementierung in einer Datei namens „ .cpp “ befindet:

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());
}

Außerdem ist für die meisten Plugins eine JSON-Datei (jsonviewer.json) erforderlich, die Metadaten zur Beschreibung des Plugins enthält. Bei Dokumenten-Viewer-Plugins enthält diese lediglich den Namen des Viewer-Plugins.

{ "Keys": [ "jsonviewer" ] }

Welche Informationen in der JSON-Datei angegeben werden müssen, hängt vom jeweiligen Plugin ab. Einzelheiten zu den Informationen, die die Datei enthalten muss, finden Sie in der Klassendokumentation.

Für Datenbanktreiber, Bildformate, Text-Codecs und die meisten anderen Plugin-Typen ist keine explizite Objekterstellung erforderlich. Qt findet und erstellt diese bei Bedarf automatisch.

Für Plugin-Klassen müssen möglicherweise zusätzliche Funktionen implementiert werden. Einzelheiten zu den virtuellen Funktionen, die für jeden Plugin-Typ neu implementiert werden müssen, finden Sie in der Klassendokumentation.

Die „Document Viewer“-Demo zeigt, wie ein Plugin implementiert wird, das strukturierte Inhalte einer Datei anzeigt. Jedes Plugin implementiert daher virtuelle Funktionen neu, die

  • das Plugin identifizieren
  • die von ihm unterstützten MIME-Typen zurückgeben
  • angibt, ob Inhalte zur Anzeige vorhanden sind, und
  • wie der Inhalt dargestellt wird
    QString viewerName() const override { return QLatin1StringView(staticMetaObject.className()); };
    QStringList supportedMimeTypes() const override;
    bool hasContent() const override;
    bool supportsOverview() const override { return true; }

Die Low-Level-API: Erweiterung von Qt-Anwendungen

Zusätzlich zu Qt selbst können Qt-Anwendungen durch Plugins erweitert werden. Dazu muss die Anwendung Plugins mithilfe von ` QPluginLoader` erkennen und laden. In diesem Zusammenhang können Plugins beliebige Funktionen bereitstellen und sind nicht auf Datenbanktreiber, Bildformate, Text-Codecs, Stile und andere Arten von Plugins beschränkt, die die Funktionalität von Qt erweitern.

Um eine Anwendung durch Plugins erweiterbar zu machen, sind folgende Schritte erforderlich:

  1. Definieren Sie eine Reihe von Schnittstellen (Klassen mit ausschließlich rein virtuellen Funktionen), die zur Kommunikation mit den Plugins dienen.
  2. Verwenden Sie das Makro ` Q_DECLARE_INTERFACE()``, um das Metaobjektsystem von Qt über die Schnittstelle zu informieren.
  3. Verwenden Sie ` QPluginLoader ` in der Anwendung, um die Plugins zu laden.
  4. Verwenden Sie ` qobject_cast()`, um zu prüfen, ob ein Plugin eine bestimmte Schnittstelle implementiert.

Das Schreiben eines Plugins umfasst folgende Schritte:

  1. Deklarieren Sie eine Plugin-Klasse, die von ` QObject ` und von den Schnittstellen erbt, die das Plugin bereitstellen soll.
  2. Verwenden Sie das Makro ` Q_INTERFACES()`, um das Metaobjektsystem von Qt über die Schnittstellen zu informieren.
  3. Exportieren Sie das Plugin mithilfe des Makros ` Q_PLUGIN_METADATA()`.

Hier ist beispielsweise die Definition einer Schnittstellenklasse:

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

Hier ist die Schnittstellendeklaration:

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

Weitere Informationen zu spezifischen Aspekten des „ Qt Widgets “-Designers finden Sie unter „Erstellen benutzerdefinierter Widgets für den Qt Widgets -Designer “. Ein Beispiel für die Verwendung eines Plugins zur Unterstützung eines benutzerdefinierten Kalendersystems finden Sie im Beispiel zum Kalender-Backend-Plugin.

Plugins finden

Qt-Anwendungen erkennen automatisch, welche Plugins verfügbar sind, da diese in den Standard-Plugin-Unterverzeichnissen gespeichert sind. Aus diesem Grund benötigen Anwendungen keinen Code zum Auffinden und Laden von Plugins, da Qt dies automatisch übernimmt.

Während der Entwicklung lautet der Pfad für Plugins „ QTDIR/plugins “ (wobei „ QTDIR “ das Verzeichnis ist, in dem Qt installiert ist), wobei jeder Plugin-Typ in einem eigenen Unterverzeichnis abgelegt ist, zum Beispiel „ styles “. Wenn Sie möchten, dass Ihre Anwendungen Plugins verwenden, und Sie nicht den Standardpfad für Plugins nutzen möchten, lassen Sie Ihren Installationsprozess den gewünschten Pfad für die Plugins ermitteln und speichern Sie diesen Pfad – beispielsweise mithilfe von ` QSettings` –, damit die Anwendung ihn bei der Ausführung lesen kann. Die Anwendung kann dann mit diesem Pfad die Funktion ` QCoreApplication::addLibraryPath()` aufrufen, und Ihre Plugins stehen der Anwendung zur Verfügung. Beachten Sie, dass der letzte Teil des Pfads (z. B. styles) nicht geändert werden darf.

Wenn Sie möchten, dass das Plugin geladen werden kann, besteht ein Ansatz darin, ein Unterverzeichnis unterhalb der Anwendung anzulegen und das Plugin in diesem Verzeichnis abzulegen. Wenn Sie eines der mit Qt mitgelieferten Plugins (die sich im Verzeichnis „ plugins “ befinden) weitergeben, müssen Sie das Unterverzeichnis unter „ plugins “, in dem sich das Plugin befindet, in den Stammordner Ihrer Anwendung kopieren (d. h., das Verzeichnis „ plugins “ darf nicht mit einbezogen werden).

Weitere Informationen zur Bereitstellung finden Sie in der Dokumentation „Bereitstellung von Qt-Anwendungen “ und „Bereitstellung von Plugins “.

Statische Plugins

Die übliche und flexibelste Methode, ein Plugin in eine Anwendung einzubinden, besteht darin, es in eine dynamische Bibliothek zu kompilieren, die separat ausgeliefert und zur Laufzeit erkannt und geladen wird.

Plugins können statisch in Ihre Anwendung eingebunden werden. Wenn Sie die statische Version von Qt erstellen, ist dies die einzige Möglichkeit, die vordefinierten Plugins von Qt einzubinden. Die Verwendung statischer Plugins macht die Bereitstellung weniger fehleranfällig, hat jedoch den Nachteil, dass keine Funktionen aus Plugins hinzugefügt werden können, ohne die Anwendung komplett neu zu kompilieren und erneut zu verteilen.

CMake und qmake fügen automatisch die Plugins hinzu, die typischerweise von den verwendeten Qt-Modulen benötigt werden, während speziellere Plugins manuell hinzugefügt werden müssen. Die Standardliste der automatisch hinzugefügten Plugins kann je nach Typ überschrieben werden.

Die Standardeinstellungen sind auf eine optimale sofortige Einsatzbereitschaft ausgelegt, können die Anwendung jedoch unnötig aufblähen. Es wird empfohlen, die Linker-Befehlszeile zu überprüfen und unnötige Plugins zu entfernen.

Damit statische Plugins tatsächlich eingebunden und instanziiert werden, sind im Anwendungscode außerdem die Makros ` Q_IMPORT_PLUGIN()` erforderlich; diese werden jedoch automatisch vom Build-System generiert und Ihrem Anwendungsprojekt hinzugefügt.

Importieren statischer Plugins in CMake

Um Plugins in einem CMake-Projekt statisch zu verknüpfen, müssen Sie den Befehl `qt_import_plugins() ` aufrufen.

Beispielsweise wird das Linux- libinput -Plugin standardmäßig nicht importiert. Der folgende Befehl importiert es:

qt_import_plugins(myapp INCLUDE Qt::QLibInputPlugin)

Um anstelle des standardmäßigen Qt Platform Adaptation-Plugins das Plugin für minimale Plattformintegration zu verknüpfen, verwenden Sie:

qt_import_plugins(myapp
    INCLUDE_BY_TYPE platforms Qt::MinimalIntegrationPlugin
)

Ein weiterer typischer Anwendungsfall ist das Einbinden nur einer bestimmten Auswahl von „ imageformats “-Plugins:

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

Wenn Sie verhindern möchten, dass imageformats -Plugins verknüpft werden, verwenden Sie:

qt_import_plugins(myapp
    EXCLUDE_BY_TYPE imageformats
)

Wenn Sie das Hinzufügen von Standard-Plugins deaktivieren möchten, verwenden Sie die Option „ NO_DEFAULT “ von ` qt_import_plugins()`.

Importieren statischer Plugins in qmake

In einem qmake-Projekt müssen Sie die erforderlichen Plugins mithilfe von ` QTPLUGIN` zu Ihrem Build hinzufügen:

QTPLUGIN += qlibinputplugin

Um beispielsweise das Minimal-Plugin anstelle des standardmäßigen Qt Platform Adaptation-Plugins zu verknüpfen, verwenden Sie:

QTPLUGIN.platforms = qminimal

Wenn Sie möchten, dass weder das Standard- noch das minimale QPA-Plugin automatisch eingebunden wird, verwenden Sie:

QTPLUGIN.platforms = -

Wenn Sie nicht möchten, dass alle zu „QTPLUGIN“ hinzugefügten Plugins automatisch eingebunden werden, entfernen Sie „ import_plugins “ aus der Variablen „ CONFIG “:

CONFIG -= import_plugins

Erstellen statischer Plugins

Es ist auch möglich, eigene statische Plugins zu erstellen, indem Sie die folgenden Schritte ausführen:

  1. Übergeben Sie die Option „ STATIC “ an den Befehl `qt_add_plugin()` in Ihrer Datei ` CMakeLists.txt`. Bei einem qmake-Projekt fügen Sie ` CONFIG += static ` in die Datei ` .pro ` Ihres Plugins ein.
  2. Verwenden Sie das Makro „ Q_IMPORT_PLUGIN()“ in Ihrer Anwendung.
  3. Verwenden Sie das Makro ` Q_INIT_RESOURCE()` in Ihrer Anwendung, wenn das Plugin qrc-Dateien enthält.
  4. Verknüpfen Sie Ihre Anwendung mit Ihrer Plugin-Bibliothek mithilfe von `target_link_libraries ` in Ihrer ` CMakeLists.txt `-Datei oder von ` LIBS ` in Ihrer ` .pro `-Datei.

Einzelheiten dazu finden Sie im „Plug & Paint “-Beispiel und im zugehörigen „Basic Tools“-Plugin.

Hinweis: Wenn Sie zum Erstellen Ihres Plugins weder CMake noch qmake verwenden, müssen Sie sicherstellen, dass das Präprozessor-Makro „ QT_STATICPLUGIN “ definiert ist.

Plugins laden

Je nach Plugin-Typ (statisch oder gemeinsam genutzt) und Betriebssystem sind unterschiedliche Vorgehensweisen zum Auffinden und Laden von Plugins erforderlich. Es ist sinnvoll, eine Abstraktion für das Laden von Plugins zu implementieren.

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

QPluginLoader::staticInstances() gibt ein ` QObjectList ` mit einem Zeiger auf jedes statisch verknüpfte Plugin zurück

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

Gemeinsam genutzte Plugins befinden sich in ihren Bereitstellungsverzeichnissen, was unter Umständen eine betriebssystemspezifische Handhabung erfordert.

   // Gemeinsame Plugins laden
    QDir pluginsDir = QDir(QApplication::applicationDirPath());
#if defined(Q_OS_DARWIN)
    if (pluginsDir.exists("../PlugIns"_L1)) { // installierte Version
        pluginsDir.cd("../PlugIns"_L1);
    } else {
        pluginsDir.cd("../../../../plugins"_L1); // nicht installierte Version
    }
#elif defined(Q_OS_WIN)
    if (pluginsDir.exists("plugins"_L1)) { // nicht installierte Version
        pluginsDir.cd("plugins"_L1);
    } else {
        pluginsDir.cd("../plugins"_L1); // installierte Version
    }
#else
    pluginsDir.cd("../plugins"_L1); // installierte und nicht installierte Version
#endif

   // qDebug("Plugins werden aus %s geladen...", 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
    }
}

Bereitstellung und Fehlerbehebung bei Plugins

Das Dokument „Bereitstellung von Plugins “ beschreibt den Prozess der Bereitstellung von Plugins mit Anwendungen sowie deren Fehlerbehebung bei auftretenden Problemen.

Siehe auch QPluginLoader und 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.