KPluginFactory Class
KPluginFactory provides a convenient way to provide factory-style plugins. More...
Header: | #include <KPluginFactory> |
CMake: | find_package(KF6 REQUIRED COMPONENTS CoreAddons) target_link_libraries(mytarget PRIVATE KF6::CoreAddons) |
Inherits: | QObject |
Public Types
(since 5.86) class | Result |
(since 5.86) enum | ResultErrorReason { NO_PLUGIN_ERROR, INVALID_PLUGIN, INVALID_FACTORY, INVALID_KPLUGINFACTORY_INSTANTIATION } |
Public Functions
KPluginFactory() | |
T * | create(QObject *parent = nullptr, const QVariantList &args = {}) |
T * | create(QWidget *parentWidget, QObject *parent, const QVariantList &args = {}) |
(since 5.77) KPluginMetaData | metaData() const |
(since 5.77) void | setMetaData(const KPluginMetaData &metaData) |
Static Public Members
(since 5.86) KPluginFactory::Result<T> | instantiatePlugin(const KPluginMetaData &data, QObject *parent = nullptr, const QVariantList &args = {}) |
(since 5.86) KPluginFactory::Result<KPluginFactory> | loadFactory(const KPluginMetaData &data) |
Protected Functions
virtual QObject * | create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args) |
void | registerPlugin() |
void | registerPlugin() |
(since 5.96) void | registerPlugin(KPluginFactory::CreateInstanceWithMetaDataFunction instanceFunction) |
Macros
(since 5.90) | K_PLUGIN_CLASS |
(since 5.44) | K_PLUGIN_CLASS_WITH_JSON |
K_PLUGIN_FACTORY | |
(since 5.0) | K_PLUGIN_FACTORY_WITH_JSON |
Detailed Description
Qt plugins provide a singleton object, but a common pattern is for plugins to generate as many objects of a particular type as the application requires. By using KPluginFactory, you can avoid implementing the factory pattern yourself.
KPluginFactory also allows plugins to provide multiple different object types, indexed by keywords.
The objects created by KPluginFactory must inherit QObject, and must have a standard constructor pattern:
- if the object is a KPart::Part, it must be of the form
T(QWidget *parentWidget, QObject *parent, const QVariantList &args)
or
T(QWidget *parentWidget, QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
- if it is a QWidget, it must be of the form
T(QWidget *parent, const QVariantList &args)
or
T(QWidget *parent, const KPluginMetaData &metaData, const QVariantList &args)
- otherwise it must be of the form
T(QObject *parent, const QVariantList &args)
or
T(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
You should typically use either K_PLUGIN_CLASS() or K_PLUGIN_CLASS_WITH_JSON() in your plugin code to generate a factory. The typical pattern is:
#include <KPluginFactory> #include <plugininterface.h> class MyPlugin : public PluginInterface { public: MyPlugin(QObject *parent, const QVariantList &args) : PluginInterface(parent) {} }; K_PLUGIN_CLASS(MyPlugin) #include <myplugin.moc>
If you want to write a custom KPluginFactory not using the standard macro(s) you can reimplement the create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args) method.
Example:
class SomeScriptLanguageFactory : public KPluginFactory { Q_OBJECT public: SomeScriptLanguageFactory() {} protected: virtual QObject *create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args) { // Create an identifier based on the iface and given pluginId const QString identifier = QLatin1String(iface) + QLatin1Char('_') + metaData().pluginId(); // load scripting language module from the information in identifier and return it: return object; } };
To load the KPluginFactory from an installed plugin you can use loadFactory() and for directly creating a plugin instance from it instantiatePlugin()
Member Type Documentation
[since 5.86]
enum KPluginFactory::ResultErrorReason
Constant | Value | Description |
---|---|---|
KPluginFactory::NO_PLUGIN_ERROR | 0 | No error |
KPluginFactory::INVALID_PLUGIN | 1 | The plugin could not be loaded |
KPluginFactory::INVALID_FACTORY | 2 | The factory object could not be loaded |
KPluginFactory::INVALID_KPLUGINFACTORY_INSTANTIATION | 3 | The target object could not be instantiated |
This enum was introduced in 5.86.
Member Function Documentation
[explicit]
KPluginFactory::KPluginFactory()
template <typename T> T *KPluginFactory::create(QObject *parent = nullptr, const QVariantList &args = {})
Use this method to create an object.
It will try to create an object which inherits T.
If it has multiple choices it's not defined which object will be returned, so be careful to request a unique interface or use keywords.
T the interface for which an object should be created. The object will inherit T.
parent the parent of the object. If parent is a widget type, it will also passed to the parentWidget argument of the CreateInstanceFunction for the object.
args additional arguments which will be passed to the object.
Returns a pointer to the created object is returned, or nullptr
if an error occurred.
template <typename T> T *KPluginFactory::create(QWidget *parentWidget, QObject *parent, const QVariantList &args = {})
Use this method to create an object. It will try to create an object which inherits T This overload has an additional parentWidget argument, which is used by some plugins (e.g. Parts).
T the interface for which an object should be created. The object will inherit T.
parentWidget an additional parent widget.
parent the parent of the object. If parent is a widget type, it will also passed to the parentWidget argument of the CreateInstanceFunction for the object.
args additional arguments which will be passed to the object. Since 5.93 this has a default arg. Returns a pointer to the created object is returned, or nullptr
if an error occurred.
[virtual protected]
QObject *KPluginFactory::create(const char *iface, QWidget *parentWidget, QObject *parent, const QVariantList &args)
This function is called when the factory asked to create an Object.
You may reimplement it to provide a very flexible factory. This is especially useful to provide generic factories for plugins implemented using a scripting language.
iface the staticMetaObject::className() string identifying the plugin interface that was requested. E.g. for KCModule plugins this string will be "KCModule".
parentWidget only used if the requested plugin is a KPart.
parent the parent object for the plugin object.
args a plugin specific list of arbitrary arguments.
[static, since 5.86]
template <typename T> KPluginFactory::Result<T> KPluginFactory::instantiatePlugin(const KPluginMetaData &data, QObject *parent = nullptr, const QVariantList &args = {})
Attempts to load the KPluginFactory and create a T instance from the given metadata.
KCoreAddons will log error messages automatically, meaning you only need to implement your own logging in case you want to give it more context info or have a custom category.
if (auto result = KPluginFactory::instantiatePlugin<MyClass>(metaData, parent, args)) { // The plugin is valid and result.plugin contains the object } else { // We can access the error related properties, but result.plugin is a nullptr qCWarning(MYCATEGORY) << result.errorString; }
If there is no extra error handling needed the plugin can be directly accessed and checked if it is a nullptr
if (auto plugin = KPluginFactory::instantiatePlugin<MyClass>(metaData, parent, args).plugin) { }
data KPluginMetaData from which the plugin should be loaded
args arguments which get passed to the plugin's constructor
Returns a Result object which contains the plugin instance and potentially error information
This function was introduced in 5.86.
[static, since 5.86]
KPluginFactory::Result<KPluginFactory> KPluginFactory::loadFactory(const KPluginMetaData &data)
Attempts to load the KPluginFactory from the given metadata.
The errors will be logged using the kf.coreaddons debug category.
data KPluginMetaData from which the plugin should be loaded
Returns a result object which contains the plugin instance and potentially error information
This function was introduced in 5.86.
[since 5.77]
KPluginMetaData KPluginFactory::metaData() const
Returns the metadata of the plugin
This function was introduced in 5.77.
See also setMetaData().
[protected]
template <typename T, KPluginFactory::enable_if_t<InheritanceChecker<T>::enabled, int> = 0> void KPluginFactory::registerPlugin()
Uses a default instance creation function depending on the type of interface. If the interface inherits from KParts::Part
the function will call
new T(QWidget *parentWidget, QObject *parent, const QVariantList &args)
QWidget
the function will call
new T(QWidget *parent, const QVariantList &args)
else the function will call
new T(QObject *parent, const QVariantList &args)
If those constructor methods are not callable this overload is not available.
[protected]
template <typename T, KPluginFactory::enable_if_t<InheritanceWithMetaDataChecker<T>::enabled, int> = 0> void KPluginFactory::registerPlugin()
Uses a default instance creation function depending on the type of interface. If the interface inherits from KParts::Part
the function will call
new T(QWidget *parentWidget, QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
QWidget
the function will call
new T(QWidget *parent, const KPluginMetaData &metaData, const QVariantList &args)
else the function will call
new T(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
If those constructor methods are not callable this overload is not available.
[protected, since 5.96]
template <typename T> void KPluginFactory::registerPlugin(KPluginFactory::CreateInstanceWithMetaDataFunction instanceFunction)
Registers a plugin with the factory. Call this function from the constructor of the KPluginFactory subclass to make the create function able to instantiate the plugin when asked for an interface the plugin implements.
T the name of the plugin class
instanceFunction A function pointer to a function that creates an instance of the plugin.
This function was introduced in 5.96.
[since 5.77]
void KPluginFactory::setMetaData(const KPluginMetaData &metaData)
Set the metadata about the plugin this factory generates.
metaData the metadata about the plugin
This function was introduced in 5.77.
See also metaData().
Macro Documentation
[since 5.90]
K_PLUGIN_CLASS
Creates a KPluginFactory subclass and exports it as the root plugin object. Unlike K_PLUGIN_CLASS_WITH_JSON, this macro does not require json meta data.
This macro does the same as K_PLUGIN_FACTORY, but you only have to pass the class name. The factory name and registerPlugin call are deduced from the class name. This is also useful if you want to use static plugins, see the kcoreaddons_add_plugin CMake method.
This macro was introduced in 5.90.
[since 5.44]
K_PLUGIN_CLASS_WITH_JSON
Create a KPluginFactory subclass and export it as the root plugin object with JSON metadata.
This macro does the same as K_PLUGIN_FACTORY_WITH_JSON, but you only have to pass the class name and the json file. The factory name and registerPlugin call are deduced from the class name.
#include <myplugin.moc>
in the same source file when that one has the name "myplugin.cpp".
Example:
#include <KPluginFactory> #include <plugininterface.h> class MyPlugin : public PluginInterface { public: MyPlugin(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args) : PluginInterface(parent) {} }; K_PLUGIN_CLASS_WITH_JSON(MyPlugin, "metadata.json") #include <myplugin.moc>
This macro was introduced in 5.44.
See also K_PLUGIN_FACTORY_WITH_JSON.
K_PLUGIN_FACTORY
Create a KPluginFactory subclass and export it as the root plugin object.
name the name of the KPluginFactory derived class.
pluginRegistrations code to be inserted into the constructor of the class. Usually a series of registerPlugin() calls.
Note: K_PLUGIN_FACTORY declares the subclass including a Q_OBJECT macro. So you need to make sure to have Qt's moc run also for the source file where you use the macro. E.g. in projects using CMake and it's automoc feature, as usual you need to have a line
#include <myplugin.moc>
in the same source file when that one has the name "myplugin.cpp".
Example:
#include <KPluginFactory> #include <plugininterface.h> class MyPlugin : public PluginInterface { public: MyPlugin(QObject *parent, const QVariantList &args) : PluginInterface(parent) {} }; K_PLUGIN_FACTORY(MyPluginFactory, registerPlugin<MyPlugin>();) #include <myplugin.moc>
If you want to compile a .json file into the plugin, use K_PLUGIN_FACTORY_WITH_JSON.
See also K_PLUGIN_FACTORY_WITH_JSON.
[since 5.0]
K_PLUGIN_FACTORY_WITH_JSON
Create a KPluginFactory subclass and export it as the root plugin object with JSON metadata.
This macro does the same as K_PLUGIN_FACTORY, but adds a JSON file as plugin metadata. See Q_PLUGIN_METADATA() for more information.
name the name of the KPluginFactory derived class.
pluginRegistrations code to be inserted into the constructor of the class. Usually a series of registerPlugin() calls.
jsonFile name of the JSON file to be compiled into the plugin as metadata
Note: K_PLUGIN_FACTORY_WITH_JSON declares the subclass including a Q_OBJECT macro. So you need to make sure to have Qt's moc run also for the source file where you use the macro. E.g. in projects using CMake and its automoc feature, as usual you need to have a line
#include <myplugin.moc>
in the same source file when that one has the name "myplugin.cpp".
Example:
#include <KPluginFactory> #include <plugininterface.h> class MyPlugin : public PluginInterface { public: MyPlugin(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args) : PluginInterface(parent) {} }; K_PLUGIN_FACTORY_WITH_JSON(MyPluginFactory, "metadata.json", registerPlugin<MyPlugin>(); ) #include <myplugin.moc>
This macro was introduced in 5.0.
See also K_PLUGIN_FACTORY.