Qt文档阅读笔记-Qt插件DECLARE_INTERFACE & METADATA & INTERFACES官方解析及实例
发布日期:2021-06-30 10:59:01
浏览次数:2
分类:技术文章
本文共 5049 字,大约阅读时间需要 16 分钟。
目录
官方解析
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_OBJECT Q_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 = PluginTEMPLATE = libCONFIG += plugin#DESTDIR = $$[QT_INSTALL_PLUGINS]/genericDEFINES += IDPLUGIN_LIBRARYDEFINES += QT_DEPRECATED_WARNINGSSOURCES += \ widgetdemo.cppHEADERS += \ widgetdemo.h \ appinterface.h \ secondplugin.hDISTFILES += Plugin.jsonunix { target.path = /usr/lib INSTALLS += target}FORMS += \ widgetdemo.ui
appinterface.h
#ifndef APPINTERFACE_H#define APPINTERFACE_H#includeclass 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_OBJECT Q_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#includenamespace 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#includeclass 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#includenamespace 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"#includeint 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#include #include #include Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget){ ui->setupUi(this); QList 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 (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;}
转载地址:https://it1995.blog.csdn.net/article/details/86540402 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2024年04月22日 08时33分40秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
C++Builder中大尺寸图像的显示技巧
2019-04-30
C++Builder中各种资源的利用
2019-04-30
画控件的几个函数
2019-04-30
C++Builder的基本功能
2019-04-30
C++Builder及VC的DLL相互调用解决方案
2019-04-30
用C++ Builder XE 10编译生成EXE运行问题
2019-04-30
BUilder高效率代码
2019-04-30
Builder聊天
2019-04-30
Builder中使用Access数据库
2019-04-30
C++ Builder VCL库函数简介
2019-04-30
DistanceInEarth
2019-04-30
earth
2019-04-30
pb6.5技巧
2019-04-30
详解Oracle数据库备份恢复
2019-04-30
诺基亚新动作!自创开源Linux内存分析器—Memory Profiler
2019-04-30
人工智能-OpenCV+Python实现人脸识别(视频人脸检测)
2019-04-30
【数据统计分析】详解Oracle分组函数之CUBE
2019-04-30
起泡法的使用
2019-04-30
中英对照表
2019-04-30
部分词汇
2019-04-30