一、源码目录: Qt\Examples\Qt-5.12.4\widgets\tools\plugandpaint
二、定义接口
class FilterInterface
{
public:
virtual ~FilterInterface() {}
virtual QStringList filters() const = 0;
virtual QImage filterImage(const QString &filter, const QImage &image,
QWidget *parent) = 0;
};
QT_BEGIN_NAMESPACE //开始命名空间,不是必要
//定义id
#define FilterInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.FilterInterface/1.0"
//注册接口
Q_DECLARE_INTERFACE(FilterInterface, FilterInterface_iid)
QT_END_NAMESPACE
二、插件端:
分两种,动态库、静态库,只是 CONFIG += plugin static(static 有无区别)
实现接口
//定义实现,继承自插件接口,也可以多继承插件接口(也就是可以一个类当多种插件)
class ExtraFiltersPlugin : public QObject, public FilterInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.PlugAndPaint.FilterInterface" FILE "extrafilters.json") //告诉MOC 导出该类
Q_INTERFACES(FilterInterface) //告诉MOC 实现那些接口
public:
QStringList filters() const override;
QImage filterImage(const QString &filter, const QImage &image,
QWidget *parent) override;
};
三、应用端
对于 静态插件
首先需要使用 Q_IMPORT_PLUGIN(BasicToolsPlugin) 进行导入
加载 静态插件
//因为使用 Q_IMPORT_PLUGIN 导入了,所以使用全局指针获取插件
const auto staticInstances = QPluginLoader::staticInstances();
for (QObject *plugin : staticInstances)
populateMenus(plugin);
//将插件转为目标接口
auto iBrush = qobject_cast<BrushInterface *>(plugin);
对于动态插件
//输入插件目录
const auto entryList = pluginsDir.entryList(QDir::Files);
for (const QString &fileName : entryList) {
QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); //根据绝对地址找插件加载
QObject *plugin = loader.instance();
if (plugin) {
populateMenus(plugin);
pluginFileNames += fileName;
}