Qt文档阅读笔记-Qt插件DECLARE_INTERFACE METADATA INTERFACES官方解析及实例
目錄
?
官方解析
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不在命名空間中,舉個栗子:
 ?
?
Q_PLUGIN_METADATA
這個宏被用于聲明元數據,這個元數據是被實例化插件的一部分。
 這個宏需要通過對象聲明被實例化接口的IID,并且要引用包含元數據內容的文件。
 在Qt插件源碼里面,應該宏應該只能出現異常。
 舉個栗子:
 通過查看 Plug & Paint例子查看細節。
 注意,這個宏只能出現在可以被實例化的類中(不能放在抽象類中)。
 FILE是可選參數,他指向一個json文件。
 這個json文件要包含在構建目錄中(為資源文件),不然moc會出錯。
?
Q_INTERFACES
此宏告訴Qt哪些接口被類實例了。這個宏通常用于插件的實例。
 舉個栗子:
 看 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.uiappinterface.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_Hsecondplugin.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_Hwidgetdemo.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_Hwidgetdemo.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_Hwidget.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_Hmain.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官方解析及实例的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: Wireshark工作笔记-TCP的状态
 - 下一篇: Qt工作笔记-QTreeWidget顺序