目录

官方解析

Q_DECLARE_INTERFACE

Q_PLUGIN_METADATA

Q_INTERFACES

博主栗子


官方解析

Q_DECLARE_INTERFACE

此宏用于把标识符与类名接口关联起来。这个标识符是唯一的,举个栗子:

  #define BrushInterface_iid "org.qt-project.Qt.Examples.PlugAndPaint.BrushInterface"Q_DECLARE_INTERFACE(BrushInterface, BrushInterface_iid)

这个宏通常在被放到一个类被定后的位置。详细内容查看 Plug & pain。
如果你想把Q_DECLARE_INTERFACE用于命名空间的接口类,要确保Q_DECLARE_INTERACE不在命名空间中,举个栗子:

  namespace Foo{struct MyInterface { ... };}Q_DECLARE_INTERFACE(Foo::MyInterface, "org.examples.MyInterface")

Q_PLUGIN_METADATA

这个宏被用于声明元数据,这个元数据是被实例化插件的一部分。
这个宏需要通过对象声明被实例化接口的IID,并且要引用包含元数据内容的文件。
在Qt插件源码里面,应该宏应该只能出现异常。
举个栗子:

  class MyInstance : public QObject{Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDummyPlugin" FILE "mymetadata.json")};

通过查看 Plug & Paint例子查看细节。
注意,这个宏只能出现在可以被实例化的类中(不能放在抽象类中)。
FILE是可选参数,他指向一个json文件。
这个json文件要包含在构建目录中(为资源文件),不然moc会出错。

Q_INTERFACES

此宏告诉Qt哪些接口被类实例了。这个宏通常用于插件的实例。
举个栗子:

  class BasicToolsPlugin : public QObject,public BrushInterface,public ShapeInterface,public FilterInterface{Q_OBJECTQ_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.PlugAndPaint.BrushInterface" FILE "basictools.json")Q_INTERFACES(BrushInterface ShapeInterface FilterInterface)public:...};

看 Plug & Paint Basic Tools例子查看细节。

博主栗子

这里举一个简单的例子,插件放到文件夹plugin中如下图所示:

运行加载插件的exe程序!

插件的界面为:

这里涉及2个程序,一个是插件端,一个是读取插件端!

插件端程序结构如下:

这里有一个关键,就是插件端,和读取插件端要统一appinterface.h文件,就和调dll,要使用.h一样的逻辑!

下面给出源码:

Plugin.pro

QT       += core gui widgetsTARGET = Plugin
TEMPLATE = lib
CONFIG += plugin#DESTDIR = $$[QT_INSTALL_PLUGINS]/generic
DEFINES += IDPLUGIN_LIBRARYDEFINES += QT_DEPRECATED_WARNINGSSOURCES += \widgetdemo.cppHEADERS += \widgetdemo.h \appinterface.h \secondplugin.h
DISTFILES += Plugin.jsonunix {target.path = /usr/libINSTALLS += target
}FORMS += \widgetdemo.ui

appinterface.h

#ifndef APPINTERFACE_H
#define APPINTERFACE_H#include <QObject>class AppInterface{
public:virtual ~AppInterface(){}virtual QString name() = 0;virtual QWidget *widget() = 0;QString libDir(){return m_libDir.isEmpty() ? "./" : m_libDir;}void setLibDir(QString libDir){m_libDir = libDir;}private:QString m_libDir;};QT_BEGIN_NAMESPACE#define Interface_iid "com.IT1995.Interface"Q_DECLARE_INTERFACE(AppInterface, Interface_iid)QT_END_NAMESPACE#endif // APPINTERFACE_H

secondplugin.h

#ifndef SECONDPLUGIN_H
#define SECONDPLUGIN_H#include "appinterface.h"
#include "widgetdemo.h"class SecondPlugin: public QObject, AppInterface{Q_OBJECTQ_PLUGIN_METADATA(IID "com.IT1995.Interface")Q_INTERFACES(AppInterface)public:QString name(){ return QStringLiteral("Second模块");}QWidget *widget(){ return new WidgetDemo(); }
};#endif // SECONDPLUGIN_H

widgetdemo.h

#ifndef WIDGETDEMO_H
#define WIDGETDEMO_H#include <QWidget>namespace Ui {
class WidgetDemo;
}class WidgetDemo : public QWidget
{Q_OBJECTpublic:explicit WidgetDemo(QWidget *parent = 0);~WidgetDemo();private:Ui::WidgetDemo *ui;
};#endif // WIDGETDEMO_H

widgetdemo.cpp

#include "widgetdemo.h"
#include "ui_widgetdemo.h"WidgetDemo::WidgetDemo(QWidget *parent) :QWidget(parent),ui(new Ui::WidgetDemo)
{ui->setupUi(this);
}WidgetDemo::~WidgetDemo()
{delete ui;
}

读取插件端结构如下:

源码如下:

appinterface.h

#ifndef APPINTERFACE_H
#define APPINTERFACE_H#include <QObject>class AppInterface{
public:virtual ~AppInterface(){}virtual QString name() = 0;virtual QWidget *widget() = 0;QString libDir(){return m_libDir.isEmpty() ? "./" : m_libDir;}void setLibDir(QString libDir){m_libDir = libDir;}private:QString m_libDir;};QT_BEGIN_NAMESPACE#define Interface_iid "com.IT1995.Interface"Q_DECLARE_INTERFACE(AppInterface, Interface_iid)QT_END_NAMESPACE#endif // APPINTERFACE_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();private:Ui::Widget *ui;
};#endif // WIDGET_H

main.cpp

#include "widget.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "appinterface.h"
#include <QDir>
#include <QPluginLoader>
#include <QMessageBox>
#include <QDebug>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);QList<AppInterface*> widgetList;QDir pluginsDir(qApp->applicationDirPath() + "/plugin");foreach(QString filename, pluginsDir.entryList(QDir::Files)){QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(filename));QObject *plugin = pluginLoader.instance();if(plugin){AppInterface *app = qobject_cast<AppInterface*>(plugin);if(app){widgetList.append(app);}}}if(widgetList.isEmpty()){QMessageBox::warning(this, "warning", "load plugin error");}else{foreach(AppInterface *w, widgetList){ui->tabWidget->addTab(w->widget(), w->name());}}
}Widget::~Widget()
{delete ui;
}

Qt文档阅读笔记-Qt插件DECLARE_INTERFACE METADATA INTERFACES官方解析及实例相关推荐

  1. Qt文档阅读笔记-Qt跨平台库(Qt基本库)

    Qt基本库是所有Qt平台的基础分.他能在所有支持开发的平台和测试平台上跑.这些库在Qt5中已经保持源代码和二进制的兼容. 基本模块(基本库)被其他特殊模块所附加. 下面是Qt基本模块(基本库)的列表: ...

  2. Qt文档阅读笔记|Qt工作笔记-setupUi官方解析与实例(widgets中界面与业务分离)

    目录 前言 官方解析 模拟界面与业务分离过程 博主栗子 前言 在最开始创建Qt项目的时候,已经默认添加好了,现在来分析下,这么做有什么意义! 官方解析 void QWidget::setupUi(QW ...

  3. Qt文档阅读笔记-Qt工作笔记-QTableWidget::selectedItems()官方解析与实例(如何进行多选)

    目录 前言 官方解析 博主例子 前言 QTableWidget::selectedItems(): 在使用QTableWidget中,可以选中多行,如何从界面获取多行的数据,可以使用selectedI ...

  4. Qt文档阅读笔记|Qt工作笔记-QMutexLocker的使用(抛出异常也能解锁)

    目录 官方解析 栗子 官方解析 重点如下: 1.QMutexLocker比QMutex的lock与unlock更加方便: 2.当函数生存周期结束后QMutexLocker会自动unlock: 3.如果 ...

  5. Qt文档阅读笔记-Qt工作笔记-QThread解析与实例(主线程发送信号给子线程)

    目录 QThread 官方解析 博主栗子 子线程发射信号给主线程 QThread 官方解析 Detailed Description QThread类提供了跨平台的线程管理的API. QThread对 ...

  6. Qt文档阅读笔记-Qt Core的官方解析

    Qt Core 目录 Getting Started Threading and Concurrent Programming Input/Output, Resources, Containers ...

  7. Qt文档阅读笔记-Qt对象模型及deleteLater()杂记

    最近主要在撸官方的自学包.在此作下简短的笔记: Qt对象模型 Qt包含的1500个类可以分为2类 1. identify types: 2. value types: identify types: ...

  8. Qt文档阅读笔记-Qt Quick 3D - Simple Example解析

    程序运行截图如下: 还是动的. 官方出这篇博文的目的是如何教我们使用Qt Quick 3D去渲染简单的场景. 首先是设置其场景. 在main.qml文件中设置整个场景,导入QtQuick3D组建,用于 ...

  9. Qt文档阅读笔记-Qt单元测试中模拟GUI事件

    这里先提下基本概念 官方的模拟GUI事件,就是调用QTest提供的函数,去模拟用户鼠标点击,用户输入等效果.从而达到模拟的功能,感觉这个功能非常的好. 如: QTest::keyClicks()主要是 ...

最新文章

  1. 干货!整理了50个 Pandas 高频使用技巧,强烈建议收藏!
  2. python3 多重列表推导式
  3. 计算勒让德多项式系数的第二种方法
  4. Boost:使用 type <>语法测试功能
  5. WebView与JavaScript交互
  6. eclipse怎么导入maven项目 eclipse导入maven项目详细教程
  7. WinDbg 查看静态变量
  8. 浮点数规格化-不同基数的规格化
  9. Android studio错误:module not specified
  10. android代码打包so,AndroidStudio jni开发入门及打包so库和jar包
  11. spring 注入 list和map及enum映射
  12. python下载后安装包在哪里找到_python安装包里idle在哪
  13. pycharm windows 重置_pycharm重置设置,恢复默认设置
  14. 成功解决win10下某些文件路径不存在问题
  15. 395. Longest Substring with At Least K Repeating Characters 1
  16. 植物大战僵尸 修改存档和金钱
  17. 2021-10-27 链表,双指针
  18. css实现图片自动渐变切换、element-plus 的修改el-table的(边框线为虚线、表头样式)
  19. 二分查找、分治算法——汉诺塔问题
  20. OCR文字识别—基于CTC/Attention/ACE的三大解码算法

热门文章

  1. 两分钟让你变成jar包制作高手
  2. 项目实施管理之系统演示
  3. 实战 | 尝鲜 Svelte 前端框架,开发读书笔记
  4. 程序员|听说你们都很好说话?你做几件事,就知道了!
  5. 听说,阿里“拆中台”了?
  6. 小白都能看懂的干货!大数据这朵“后浪”,能卷起多大的风浪?
  7. 《福布斯》:微软的印度未来
  8. 2020年最具“钱途”的编程语言
  9. 滴滴不倒闭,世界和中国的奇迹!
  10. 女程序员,说多了都是泪!