开发环境
Qt版本:Qt5.9.7
编译套件:msvc2015-64bit
Qt插件分类
Qt插件分为低级插件和高级插件,所谓的高级插件是在Qt已经存在的接口插件上实现扩展,Qt还是提供了很多的多媒体的插件供开发者使用,比如QAudioSystemPlugin、QMediaResourcePolicyPlugin等;低级插件则自己定义接口,自己来实现,本篇主要讲解低级插件的编写及使用。
Qt插件可以做成动态插件,使用QPluginLoader类来加载,也可以做成静态插件,两者的不同点区别在于pro文件配置上。静态插件主要在pro中添加CONFIG += static,在使用上,需要主程序中通过Q_IMPORT_PLUGIN() 来导入插件,在主程序的pro中还需要配置LIBS来链接插件库。静态插件在使用上不灵活,一般使用QPluginLoader来加载插件。
插件实现
插件的接口定制为纯虚函数,并使用Q_DECLARE_INTERFACE进行声明,如下:
#include <QtPlugin>
class WidgetInterface
{
public:
virtual ~WidgetInterface()
{
}
virtual QWidget* getWidget() = 0;
};
Q_DECLARE_INTERFACE(WidgetInterface, "Nt.Widget.Interface/1.0")
然后我们来实现这个接口,在实现类中要用宏Q_INTERFACES声明一下接口类来达到反射的作用,WidgetPlugin.json文件可以存放插件本身的信息(插件名称、插件版本等),如下:
class WidgetPlugin : public QObject, public WidgetInterface
{
Q_OBJECT
//给插件取一个唯一的id并注册到元对象系统中
Q_PLUGIN_METADATA(IID "qt-project.WidgetInterface.WidgetPlugin" FILE "WidgetPlugin.json")
Q_INTERFACES(WidgetInterface)
public:
explicit WidgetPlugin();
virtual ~WidgetPlugin() Q_DECL_OVERRIDE;
public:
virtual QWidget *getWidget() Q_DECL_OVERRIDE;
};
#include "widgetplugin.h"
WidgetPlugin::WidgetPlugin()
{
}
WidgetPlugin::~WidgetPlugin()
{
}
QWidget *WidgetPlugin::getWidget()
{
//这里可以自己定义插件的窗口类
return new QWidget();
}
这样,我们就能得到一个简单的自定义插件,下面我们将介绍如何加载插件。
插件的pro文件:
QT += widgets
TEMPLATE = lib
CONFIG += C++11 plugin
TARGET = WidgetPlugin
DISTFILES += \
widgetplugin.json
HEADERS += \
widgetplugin.h
SOURCES += \
widgetplugin.cpp
加载插件
我们使用QPluginLoader来加载插件,如下所示:
QString t_pluginPath = "";//插件所在路径
auto plugin = new QPluginLoader(t_pluginPath);
//获取插件josn文件中信息
QString key = plugin->metaData().value("MetaData").toObject().value("key").toString();
if(plugin->load())
{
//插件窗口
auto interface = qobject_cast<WidgetInterface*>(plugin->instance());
if(Q_NULLPTR != interface)
{
//这里我们都能获取插件的窗口
}
}
结束语
插件的使用能够很好的扩展应用程序功能,主程序假设有4个界面块,可以使用插件分别实现,降低程序的耦合度,但是插件之间数据交互如何实现的?下篇文章我们再来分析