怎样开发Qt插件,能够在Qt Assistant 中搜索"Qt Plugins"或"How to Create Qt Plugins",看看那篇manual中的介绍。

当中涉及到了几个宏





Q_DECLARE_INTERFACE( ClassName, Identifier)

This macro associates the given Identifier (a string literal) to the interface class called ClassName. The Identifier must be unique.

This macro is normally used right after the class definition for ClassName, in a header file.



Q_INTERFACES(...)

This macro tells Qt which interfaces the class implements. This is used when implementing plugins.



Q_PLUGIN_METADATA(...)

This macro is being used to declare meta data that is part of a plugin that instantiates this object.

The macro needs to declare the IID of the interface implemented through the object, and reference a file containing the meta data for the plugin.

There should be exactly one occurrence of this macro in the source code for a Qt plugin.



当中,Q_PLUGIN_METADATA(...)宏在前面讲“Qt插件的元信息”的那篇文章中已经介绍过了,它基本是这些宏里最重要的一个。由于

MOC会依据这个宏生成非常多跟该插件相关的东西,包含元信息、获取插件实例的函数等。可用它能够将插件导出,其作用类似于老版本号

Qt中的 Q_EXPORT_PLUGIN2 宏



Q_DECLARE_INTERFACE 宏是与qobject_cast相关的,它为接口类定义了qobject_interface_iid和qobject_cast这两个模板

Qt的源代码中给出了宏Q_DECLARE_INTERFACE的定义

  1. # define Q_DECLARE_INTERFACE(IFace, IId) \
  2. template <> inline const char *qobject_interface_iid<IFace *>() \
  3. { return IId; } \
  4. template <> inline IFace *qobject_cast<IFace *>(QObject *object) \
  5. { return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : 0)); } \
  6. // qt_metacast通过插件的IID来映射接口类的指针。一个IID绑定一个接口类
  7. template <> inline IFace *qobject_cast<IFace *>(const QObject *object) \
  8. { return reinterpret_cast<IFace *>((object ?
  9.  
  10. const_cast<QObject *>(object)->qt_metacast(IId) : 0)); }

Q_INTERFACES宏也是与qobject_cast相关,没有Q_DECLARE_INTERFACE和Q_INTERFACES这两个宏。就无法对从插件中获取的实例指针进行qobject_cast映射。

只是。Q_INTERFACES宏并没有在Qt的源代码中定义。他是MOC的菜,MOC会利用这个宏生成一些代码。要注意一点,假设一个头文件或源文件里用到了Q_INTERFACES宏,

那么在调用这个宏之前。必须存在一个 Q_DECLARE_INTERFACE宏声明对应的接口(或者包括一个用Q_DECLARE_INTERFACE宏声明了该接口的头文件),MOC会检查这一点,由于它在为Q_INTERFACES宏生成代码时要用到Q_DECLARE_INTERFACE宏的IID參数。

举例,

头文件 MyPluginInterface.h 中虚拟接口类的定义例如以下

  1. #include <QtPlugin>
  2. #define QtPluginDemo_iid "org.qt-project.Qt.PluginDemo" // 定义接口的IID
  3. class MyPluginInterface
  4. {
  5. public:
  6. virtual ~MyPluginInterface(){}
  7. virtual void showPluginName();
  8. };
  9. Q_DECLARE_INTERFACE ( MyPluginInterface, QtPluginDemo_iid ) ;

头文件MyPlugin.h中类的定义例如以下

  1. class MyPlugin : public QObject, public MyPluginInterface
  2. {
  3. Q_OBJECT
  4. // Q_PLUGIN_METADATA ( IID QtPluginDemo_iid FILE "MyPlugin.json")
  5. Q_PLUGIN_METADATA ( IID QtPluginDemo_iid)
  6. Q_INTERFACES(MyPluginInterface)
  7.  
  8. public:
  9. void showPluginName();
  10. };

将头文件MyPlugin.h用MOC处理之后。生成的代码中有例如以下部分

(仅仅列出了MOC为Q_INTERFACES宏生成的代码,MOC为Q_PLUGIN_METADATA宏生成的代码在前面讲“Qt插件的元信息”的那篇文章中介绍过了):

  1. ...
  2. ...
  3.  
  4. static const qt_meta_stringdata_MyPlugin_t qt_meta_stringdata_MyPlugin = {
  5. {
  6. QT_MOC_LITERAL(0, 0, 8)
  7. },
  8. "MyPlugin"
  9. };
  10. ...
  11. ...
  12.  
  13. void *MyPlugin::qt_metacast(const char *_clname) // Q_DECLARE_INTERFACE宏就是利用这个函数实现的qobject_cast类型映射
  14. {
  15. if (!_clname) return 0;
  16. if (!strcmp(_clname, qt_meta_stringdata_MyPlugin.stringdata)) // 假设_clname与类的名称MyPlugin匹配,返回有效指针
  17. return static_cast<void*>(const_cast< MyPlugin*>(this));
  18. if (!strcmp(_clname, "MyPluginInterface")) // 假设_clname与接口类的名称MyPluginInterface匹配,返回有效指针
  19. return static_cast< MyPluginInterface*>(const_cast< MyPlugin*>(this));
  20. if (!strcmp(_clname, "org.qt-project.Qt.PluginDemo")) // 假设_clname与接口类的IID匹配,返回有效指针。
  21. // 这里就用到了调用Q_DECLARE_INTERFACE宏时使用的IID參数
  22. // 并且,Q_DECLARE_INTERFACE宏的代码中也是利用IID映射实现的qobject_cast
  23. return static_cast< MyPluginInterface*>(const_cast< MyPlugin*>(this));
  24. return QObject::qt_metacast(_clname);
  25. }
  26. ...
  27. ...

Qt5的插件机制(6)--开发Qt插件时几个重要的宏的更多相关文章

  1. Qt5该插件机制(4)--QtMeta信息窗口小部件metaData

    <<<<<<<<<<<<<<<<<<<<<<<<< ...

  2. 设置qt插件路径

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

  3. Qt5的插件机制(1)--Qt 框架中的插件载入机制概述

    概述 Qt的源代码中通过 Q<pluginType>Factory.Q<pluginType>Plugin 和 Q<pluginType> 这三个类实现了Qt的插件 ...

  4. QT5.7静态编译(使用VS2013与VS2015编译,XP可用,有详细configure脚本。VS下Qt插件的配置。编译选项加上-mp可以开启多线程编译,编译速度提高2倍以上)

    http://blog.csdn.net/u011964923/article/details/52886908 configure -confirm-license -opensource -pla ...

  5. Qt5该插件机制(2)--QxxxFactory类和QFactoryLoader类别

    <<<<<<<<<<<<<<<<<<<<<<<<< ...

  6. 使用 PySide2 开发 Maya 插件系列三:qt语言国际化(internationalization)

    使用 PySide2 开发 Maya 插件系列三:qt语言国际化(internationalization) 前言: 这是 qt for python 的语言国际化,基于 UI 的,python 也有 ...

  7. 使用 PySide2 开发 Maya 插件系列一:QT Designer 设计GUI, pyside-uic 把 .ui 文件转为 .py 文件

    使用 PySide2 开发 Maya 插件系列一:QT Designer 设计GUI, pyside-uic 把 .ui 文件转为 .py 文件 前期准备: 安装 python:https://www ...

  8. Win7下安装VS2017、安装Qt5.10.1以及在VS2017添加qt插件

    一.安装VS2017 1.下载VS2017 进入vs下载官网https://www.visualstudio.com/zh-hans/downloads/,选择所需要的vs版本,进行在线安装. 2.安 ...

  9. 微信开发学习日记(八):7步看懂weiphp插件机制,核心目标是响应微信请求

    又经过了几个小时的梳理.回顾,截至目前,终于对weiphp这个框架的机制搞明白了些.想要完全明白,自然还需要大把的时间.第1步:   配置微信公众号,http://weiphp.jiutianniao ...

随机推荐

  1. you build it,you run it

    this article is almostly about  a book named Migrating_to_Microservices_Databases, and it's just the ...

  2. springmvc始终跳转至首页,不报404错误

    本篇博客特别补充:2017-3-4 9:42,经过分析和测试,本篇博客的解决方案只是碰巧,暂时的解决了问题.在后续的运行中,又出现了同样的毛病.经过日志跟踪,发现了端倪,下篇博客深入的剖析!本篇博客, ...

  3. 修改mysql数据的字符集校验规则使其区分大小写

    mysql 使用utf8字符集默认的校验规则collate为utf8_general_ci,不区分数据的大小写 测试如下 ::) character set utf8 collate utf8_bin ...

  4. HDU1877 又一版 A+B

    Problem Description 输入两个不超过整型定义的非负10进制整数A和B(<=231-1),输出A+B的m (1 < m <10)进制数.   Input 输入格式:测 ...

  5. 具体knn算法概念参考knn代码python实现

    具体knn算法概念参考knn代码python实现上面是参考<机器学习实战>的代码,和knn的思想 # _*_ encoding=utf8 _*_ import numpy as npimp ...

  6. 设计模式(Java随笔)—装饰模式

    装饰模式(Decorator Pattern):为已有功能动态地添加更多功能的一种方式Attach additional responsiblities to an object dynamicall ...

  7. hdu 6119 小小粉丝度度熊

    小小粉丝度度熊 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  8. 41深入理解C指针之---指针与栈

    一.借助第40指针与链表的相关内容,稍微修改即可: 1.定义头文件stack.h代码如下: #include <stdlib.h> #include <stdio.h> #if ...

  9. 反汇编->C++虚函数深度分析

    先来查看一简单例子 #include<iostream> using namespace std; class Base{ public: virtual void f() { cout ...

  10. 在 Mac OS X 环境中从源代码编译安装 FFmpeg

    最近因为一个项目要求,需要开发实时视频编解码功能,准备采用 FFmpeg 以 x264 方式进行实时的视频编解码.Windows 以及 Linux 环境下的 FFmpeg 动态库.头文件等资源都非常容 ...