如何创建 Qt 插件?

简单三部曲

  1. 定义接口类或接口基类并使用 Q_DECLARE_INTERFACE 宏进行声明
  2. 所有的插件都需要继承该基类并继承 QObject(不带界面插件) or QWidget(带界面插件)
  3. 在插件类中添加 Q_PLUGIN_METADATA 导出元数据,使用 Q_INTERFACES 指定继承基类(该基类需要使用 Q_DECLARE_INTERFACE 声明过)

如何生成?

示例

*.pro 文件内容如下

# 插件依赖模块
QT += core gui widgets # 生成目标文件名称
TARGET = FlowWidget
TEMPLATE = lib
CONFIG += plugin # 插件输出目录
DESTDIR = $$[QT_INSTALL_PLUGINS]/generic DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \
flowWidget.cpp HEADERS += \
flowWidget.h DISTFILES += FlowWidget.json include($$PWD/interface/interface.pri)

interface.pri 内容如下:

SOURCES += \

HEADERS += \
$$PWD/flowInterface.h INCLUDEPATH += $$PWD

纯接口类定义如下:

#include <QtPlugin>
class QImage;
class QString;
class QWidget;
class FlowInterface
{
public:
FlowInterface() {}
virtual ~FlowInterface() {}
virtual void process() = 0;
/*!
属性页
*/
virtual QWidget *propertyPage() = 0;
}; #define FlowInterface_iid "com.xiongwei.cheung.FlowInterface" Q_DECLARE_INTERFACE(FlowInterface, FlowInterface_iid)

注意:在插件类中我们需要实现接口中定义的纯虚函数

插件定义分为带界面和不带界面两种,采用多重继承的方式分别继承 QWidget 或 QObject 即可.

  1. 带界面插件定义如下:
class FlowWidget : public QWidget , FlowInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.xiongwei.cheung.FlowWidget" FILE "FlowWidget.json")
Q_INTERFACES(FlowInterface)
public:
explicit FlowWidget(QWidget *parent = nullptr);
void process();
QWidget *propertyPage();
signals: public slots: private: }; FlowWidget::FlowWidget(QWidget *parent) : QWidget(parent)
{ } void FlowWidget::process()
{
// to do something
} QWidget *FlowWidget::propertyPage()
{
return this;
}

FlowWidget.json 文件是可选的,可通过该文件实现密钥插件

{
"Keys" : [ "FlowWidget" ]
}
  1. 不带界面插件定义如下:
class FlowObject : public QObject , FlowInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.xiongwei.cheung.FlowObject")
Q_INTERFACES(FlowInterface)
public:
explicit FlowObject(QObject *parent = nullptr);
void process();
QWidget *propertyPage();
signals: public slots: private: }; FlowObject::FlowObject(QObject *parent) : QObject(parent)
{ } void FlowObject::process()
{
// to do something
} QWidget *FlowObject::propertyPage()
{
return nullptr;
}

如何使用?

main.cpp 文件中添加插件加载路径

QCoreApplication::applicationDirPath().append("\generic");

在工程文件中包含插件接口基类文件 flowInterface.h

#include <QPluginLoader>
#include "flowInterface.h" void load()
{
// 添加一个枚举目录所有动态库文件即可加载所有插件
QPluginLoader pluginLoader("FlowWidget.dll");
// 打印插件元数据,即 json 文件内容中的键值数据
qDebug() << pluginLoader.metaData();
// 加载该插件
QObject *plugin = pluginLoader.instance();
if (plugin) {
// 转换成接口基类指针
FlowInterface *p = qobject_cast<FlowInterface *>(plugin);
if (p){
// 显示界面
p->propertyPage()->show();
} }
}

注意一个插件类中只能存在一个 Q_PLUGIN_METADATA 宏,使用该宏会导出 qt_plugin_instanceqt_plugin_query_metadata 俩个函数。

显然如果使用 2 次 Q_PLUGIN_METADATA 宏会导致函数重定义.

实际上如果向导出多个插件的可以使用 QGenericPlugin 的手法根据 keys and `` 创建不同的对象.

如何创建 Qt 插件?的更多相关文章

  1. [Qt Creator 快速入门] 第9章 国际化、帮助系统和Qt插件

    一.国际化 国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),一个应用程序的国际化就是使该应用程序可以让其他国家的用户使用的过程. Qt支持现在 ...

  2. [Qt插件]-03创建Qt Designer自定义部件

    如何创建自定义部件并添加到Qt Designer来爽快的拖动部件可视化界面设计?   Qt Designer基于插件的架构使得它可以使用用户设计或者第三方提供的自定义部件,就像使用标准的Qt部件一样. ...

  3. [Qt插件]-02创建应用程序插件(插件化开发的一种思路)

    本篇是学习Qt Creator快速入门,插件开发的笔记   分为两部分 创建插件 使用插件的应用程序(测试插件)   插件是被使用的应用程序加载使用的. 是使用插件的应用程序定义接口,插件按照接口来实 ...

  4. VS2013中使用QT插件后每次重新编译问题

    环境 系统:win7 64位旗舰版 软件:VS2013.QT5.5.1-32位.Qt5 Visual Studio Add-in1.2.4 概述 使用QT Visual Studio插件打开pro项目 ...

  5. VS2017上在线和离线安装Qt插件(在线安装)

    版权声明:如需转载,请告知博主并声明出处 https://blog.csdn.net/CLinuxF/article/details/88816436文章目录前言在线安装离线安装(推荐)前言很多朋友喜 ...

  6. 【Win10+eclipse+MinGW+QT安装教程】已有eclipse环境下配置QT插件出错详解

    (纪念一下装了一整天濒临绝望的自己[/doge]) (以下所有下载项一律使用32位) step1:下载安装eclipse.适配的jdk.MinGW和QT 1.下载32位eclipse for c++以 ...

  7. 设置qt插件路径

    1.在Qt中使用 WebKit 浏览器核心 使用 QtWebKit 需要在工程文件(*.pro)中加入: QT +=webkitQT += network 2.QtWebKit的flash支持 QtW ...

  8. Qt 插件学习(一)

    插件是什么 注意:这儿暂时不考虑静态插件(潜意识中总觉得它根本就不算插件). 插件是一个动态库(共享库).动态库是一个独立的文件中的独立模块,可被多个程序访问. 先看动态库的两种用法 1. 程序链接时 ...

  9. [Qt插件]-01Qt插件&&提升部件(自定义控件)

    本篇的文档为:How to Create Qt Plugins https://doc.qt.io/qt-5/plugins-howto.html   前言 Qt插件(Qt Plugin)就是一个共享 ...

随机推荐

  1. 使用Jmeter聚合报告生成对比图表

    背景 最近在帮别的项目组执行性能测试,使用的工具是Jmeter.接口录制和参数化前一个人已经做好了,我主要的工作就是执行脚本,撰写测试报告.事情并不复杂,可做起来却极为耗时. 首先,由于有6组账号,分 ...

  2. Java版基于SpringBoot+Vue.js实现自动创表自动定时采集(各个微信公众号商城产品进行采集)-爬虫篇

  3. koa2 进阶网站

    http://www.ruanyifeng.com/blog/2017/08/koa.html  阮一峰 https://www.itying.com/koa/ koa2中文网 https://blo ...

  4. Python语言为什么被称为高级程序设计语言?

    Python是一种令人惊叹的编程语言,毫无疑问.从1991年的卑微开始,它现在几乎无处不在.无论您是在进行Web开发,系统管理,测试自动化,devop还是数据科学,Python在您的工作中发挥作用的可 ...

  5. Oracle12c创建及删除PDB

    在12C R1版本中只支持Global Shared Undo模式,所有container共享一个UNDO表空间:在12C R2引入了PDB Local Undo模式,每个container都有自己的 ...

  6. python学习笔记(二十):异常处理

    def calc(a,b): res=a/b return res def main(): money=input('输入多少钱:') months=input('还几个月:') try: res=c ...

  7. Xib中用自动布局设置UIScrollView的ContenSize

    1. 在UIScrollView上拖一个UIView 2.设置UIScrollView上下左右约束为0,设置UIView上下左右约束为0,并且设置水平中线约束.那么可以把水平中线约束拖到对应视图,利用 ...

  8. Python_005(字典无极坑)

    一.字典(dict) 1.字典的定义格式:dic{key1:value1,key2,value2} :这里面key是唯一的,保存的时候,根据key计算一个内存地址,然后将key-value保存在这个地 ...

  9. 一个关于 ie 浏览器的 bug 解决过程和思考

    首先我们测试了老师反馈的异常情况.这所中学使用的是 IE8 浏览器.IE8 浏览器提交作文评分的情况是:一直停留在“正在提交系统评分”的页面,停留了很长时间以后,页面空白. 换用火狐浏览器,可以正常评 ...

  10. JavaBean属性和成员变量的区别和联系

    JavaBeans是Java中一种特殊的类,可以将多个对象封装到一个对象(bean)中.特点是可序列化,提供无参构造器,提供getter方法和setter方法访问对象的属性.名称中的“Bean”是用于 ...