中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

怎樣在工商局網站做公示網絡營銷案例及分析

怎樣在工商局網站做公示,網絡營銷案例及分析,wordpress 整站下載,網站開發(fā)平臺簡介: 插件(Plug-in,又稱addin、add-in、addon或add-on,又譯外掛)是一種遵循一定規(guī)范的應用程序接口編寫出來的程序。 Qt 提供了2種APIs來創(chuàng)建插件: 一種高級API,用于為Qt本身編寫插件:自定義數據庫驅動程序,圖像格…

簡介:

插件(Plug-in,又稱addin、add-in、addon或add-on,又譯外掛)是一種遵循一定規(guī)范的應用程序接口編寫出來的程序。

Qt 提供了2種APIs來創(chuàng)建插件:

一種高級API,用于為Qt本身編寫插件:自定義數據庫驅動程序,圖像格式,文本編解碼器,自定義樣式等。

一種用于擴展Qt應用程序的低級API。也就是說擴展我們自己使用Qt編寫的程序。這要求應用程序使用 QPluginLoader 檢測和加載插件。在這種情況下,插件可以提供任意功能,不限于數據庫驅動程序、圖像格式、文本編解碼器、樣式以及擴展Qt功能的其他類型的插件。本文主要通過示例來展示第二種方式創(chuàng)建插件。

原理:

重載了虛函數的dll,這跟抽象工廠類類似,這便是插件的原理。qt的插件可以說是一種動態(tài)庫

Qt插件特點:

核心技術:QPluginLoader

Qt插件存儲在共享庫(DLL)中(即以動態(tài)庫的方式存在),與使用QLibrary訪問的共享庫相比,它具有以下優(yōu)勢:

面向Interface編程,內部封裝,模塊和整體流程開發(fā)分離,提高開發(fā)效率。

QPluginLoader 檢查插件是否與應用程序相同版本的 Qt 鏈接。

QPluginLoader 提供對根組件對象 (instance()) 的直接訪問,而不是強制您手動解析 C 函數

插件

插件主要面向接口編程,無需訪問.lib文件,熱插拔、利于團隊開發(fā)。即使在程序運行時.dll不存在,也可以正常啟動,只是相應插件功能無法正常使用而已;

動態(tài)庫

動態(tài)庫需要訪問.lib文件,而且在程序運行時必須保證.lib存在,否則無法正常啟動

開發(fā)測試環(huán)境:QT5.15.2 + MSVC 2019

在容器端:

  1. 定義一組接口(只有純虛函數的類)。
  2. 在QT_BEGIN_NAMESPACE和QT_END_NAMESPACE之間使用Q_DECLARE_INTERFACE()宏告訴Qt的元對象系統(tǒng)有關接口的信息。
  3. 在程序中使用 QPluginLoader加載插件。
  4. 使用qobject_cast()測試插件是否實現給定的接口。

Q_DECLARE_INTERFACE

Q_DECLARE_INTERFACE(類名,標識符)

此宏用于把標識符與類名接口關聯起來。這個標識符是唯一的,這個宏通常在被放到一個類被定后的位置。

這個是Qt實現插件必須要有的一個宏, 把標識符與類名接口關聯起來。

在插件端:

聲明一個插件類,該類繼承自QObject和插件要提供的接口類。

使用Q_INTERFACES()宏告訴Qt的元對象系統(tǒng)有關接口的信息。

使用Q_PLUGIN_METADATA()宏導出插件。

Q_PLUGIN_METADATA
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.SubPlugin" FILE "SubPlugin.json")

這個宏第一次參數定義了一個uuid,保證唯一即可,第二個json是必須要有的,當無法找到指定的文件時,moc 會出現錯誤,即使是空的文件也行

SubPlugin.json文件存放在源代碼目錄下,可以記錄一下插件的信息(如插件名稱、插件版本、插件依賴庫),如下

{

????"name": "testSubPlugin",

????"version": "1.0",

????"dependencies": []

}

這個宏被用于聲明元數據,這個元數據是被實例化插件的一部分。

這個宏需要通過對象聲明被實例化接口的IID,并且要引用包含元數據內容的文件。

需要獲取這些元數據(即上面的json數據),可在在通過下面的辦法。

????????QPluginLoader *loader = new QPluginLoader(this);

????????loader->setFileName(plugin.absoluteFilePath());

????????qDebug()<<loader->metaData().keys();

????????QJsonObject json = loader->metaData().value("MetaData").toObject();

????????QVariant var = json.value("name").toVariant();

Q_INTERFACES

Q_INTERFACES(AppInterface) ??//聲明這個插件實現是基于哪個插件接口的,使qobject_cast()能正確進行QObject*到接口指針的轉換

QPluginLoader?

~QPluginLoader()

銷毀 QPluginLoader 對象。

除非顯式調用 unload(),否則插件會一直保留在內存中,直到應用程序終止。

Load

加載插件,如果插件加載成功則返回true; 否則返回false。

unload

卸載插件,如果插件可以卸載則返回true,否則返回false。

這在應用程序終止時自動發(fā)生,因此通常不需要調用此函數。

如果 QPluginLoader 的其他實例正在使用相同的插件,則調用將失敗,并且只有在每個實例都調用了 unload() 時才會發(fā)生卸載。

不要嘗試刪除根組件。 而是依靠 unload() 會在需要時自動刪除它

Instance

返回插件的根組件對象,組件對象是一個 QObject。 使用 qobject_cast() 可將其轉成所需的對象。如果根組件對象被銷毀,則調用此函數會創(chuàng)建一個新實例。

該函數返回的根組件在 QPluginLoader 銷毀時不會被刪除。 如果要確保刪除根組件,則應在不再需要訪問核心組件時立即調用 unload()。 當庫最終卸載時,根組件將自動刪除。

metaData

返回此插件的元數據。 元數據是在編譯插件時使用 Q_PLUGIN_METADATA() 宏以 json 格式指定的數據。

例子

首先創(chuàng)建一個Qt Subdirs Project工程PluginDemo,并添加一個app應用程序端。并在app.pro添加輸出目錄DESTDIR = $$PWD/../bin

  1. 然后添加一個appinterface.h的頭文件,該類作為插件接口類。
#ifndef APPINTERFACE_H#define APPINTERFACE_H#include <QList>#include <QAction>class AppInterface{public:virtual ~AppInterface() {}// 插件的名字virtual QString name() const = 0;// 插件返回的QAction列表virtual QList<QAction *> actions() const = 0;};QT_BEGIN_NAMESPACEQ_DECLARE_INTERFACE(AppInterface, "plugindemo_app_interface")QT_END_NAMESPACE#endif // APPINTERFACE_H
  1. 在工程上右鍵,選擇新子項目,選擇Library->C++ Library類型選擇“shared Library”,qt module 選擇“widgets”.插件名稱為subplugin.
  2. 修改subplugin.pro

添加CONFIG+=plugin??//目的就是為是該dll作為插件

target.path = $$PWD/../bin/pluginsINSTALL+=target?//把插件dll拷貝到容器的bin目錄下。需構建步驟添加 make install

  1. 實現接口類SubPlugin.h,注意添加Q_INTERFACESQ_PLUGIN_METADATA
#ifndef SUBPLUGIN_H#define SUBPLUGIN_H#include "subPlugin_global.h"#include "../app/appinterface.h"#include <QObject>class SUBPLUGIN_EXPORT SubPlugin : public QObject, public AppInterface{public:SubPlugin();Q_OBJECTQ_INTERFACES(AppInterface) ??//聲明這個插件實現是基于哪個插件接口的Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.SubPlugin" FILE "SubPlugin.json") ?//使用Q_PLUGIN_METADATA宏導出插件// AppInterface interfacepublic:virtual QString name() const override;virtual QList<QAction *> actions() const override;};#endif // SUBPLUGIN_H#include "subplugin.h"SubPlugin::SubPlugin(){}QString SubPlugin::name() const{return "SubPlugin";}QList<QAction *> SubPlugin::actions() const{QAction *aboutQt = new QAction;aboutQt->setText(tr("About Qt"));QList<QAction *> result;result << aboutQt;return result;}
  1. 在容器的Dialog.cpp里面添加加載插件的代碼
#include "dialog.h"#include "ui_dialog.h"#include "appinterface.h"#include <QDebug>#include <QPluginLoader>#include <QFileInfo>#include <QDir>#include <QPushButton>Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog){loadPlugins();ui->setupUi(this);}Dialog::~Dialog(){delete ui;}void Dialog::loadPlugins(){QString pluginPath = QCoreApplication::applicationDirPath() + "/plugins";QStringList filters;#if defined(Q_OS_LINUX)filters << "*.so";#elif defined(Q_OS_WIN)filters << "*.dll";#endifQFileInfoList plugins = QDir(pluginPath).entryInfoList(filters,QDir::Files | QDir::NoSymLinks);for (int i = 0; i < plugins.count(); ++i) {QFileInfo plugin = plugins.at(i);QPluginLoader *loader = new QPluginLoader(this);loader->setFileName(plugin.absoluteFilePath());qDebug()<<loader->metaData().keys();QJsonObject json = loader->metaData().value("MetaData").toObject();QVariant var = json.value("name").toVariant();bool result = loader->load();qDebug() << QString("load plguin %1 result: ").arg(plugin.absoluteFilePath()) << result;if (result) {QObject *pluginInstance = loader->instance();AppInterface *appInterface = qobject_cast<AppInterface *>(pluginInstance);if (appInterface != nullptr) {qDebug() << "add actions from plugin:" << appInterface->name();QList<QAction *> actions = appInterface->actions();for (int k = 0; k < actions.count(); ++k) {QAction *ac = actions.at(k);QString strtext = ac->text();}}} else {qDebug() << loader->errorString();}}}

插件管理

自定義pluginmanager類,封裝成dll

管理所有插件,包括加載、卸載等。并暴露方法給主程序。

插件管理器代碼

插件接口

#ifndef PLUGININTERFACE_H#define PLUGININTERFACE_H#include <QtWidgets/qwidget.h>#include <QString>class PluginInterface{public:virtual ~PluginInterface() {}// 插件返回的QAction列表virtual QString datawrite() = 0;};Q_DECLARE_INTERFACE(PluginInterface, "PluginManager.PluginInterface")#endif // PLUGININTERFACE_H

插件管理器

#ifndef PLUGINMANAGER_H#define PLUGINMANAGER_H#include "PluginManager_global.h"#include <QObject>#include <QPluginLoader>class PLUGINMANAGER_EXPORT PluginManager:public QObject{Q_OBJECTprivate:PluginManager();public:static PluginManager *getinstance();//加載所有插件void loadAllPlugins();//卸載所有插件void unloadAllPlugins();QString datawrite();private:static PluginManager *m_instance;QHash<QString, QPluginLoader *>m_loaders; //插件路徑--QPluginLoader實例};#endif // PLUGINMANAGER_H#include "pluginmanager.h"#include <QDebug>#include <QPluginLoader>#include <QFileInfo>#include <QDir>#include <QCoreApplication>#include"PluginInterface.h"PluginManager* PluginManager::m_instance=nullptr;PluginManager::PluginManager(){}PluginManager *PluginManager::getinstance(){if(m_instance==nullptr)m_instance= new PluginManager();return m_instance;}void PluginManager::loadAllPlugins(){QString pluginPath = QCoreApplication::applicationDirPath() + "/plugins";QStringList filters;#if defined(Q_OS_LINUX)filters << "*.so";#elif defined(Q_OS_WIN)filters << "*.dll";#endifQFileInfoList plugins = QDir(pluginPath).entryInfoList(filters,QDir::Files | QDir::NoSymLinks);for (int i = 0; i < plugins.count(); ++i){QFileInfo plugin = plugins.at(i);QPluginLoader *loader = new QPluginLoader(this);loader->setFileName(plugin.absoluteFilePath());qDebug()<<loader->metaData().keys();QJsonObject json = loader->metaData().value("MetaData").toObject();QVariant var = json.value("name").toVariant();bool result = loader->load();qDebug() << QString("load plguin %1 result: ").arg(plugin.absoluteFilePath()) << result;if (result){m_loaders.insert(plugin.absoluteFilePath(), loader);QObject *pluginInstance = loader->instance();PluginInterface *appInterface = qobject_cast<PluginInterface *>(pluginInstance);if (appInterface != nullptr){}}else{qDebug() << loader->errorString();}}}void PluginManager::unloadAllPlugins(){for(auto filepath : m_loaders.keys()){QPluginLoader *loader = m_loaders.value(filepath);//卸載插件,并從內部數據結構中移除if(loader->unload()){m_loaders.remove(filepath);delete loader;loader = nullptr;}}}QString PluginManager::datawrite(){QString str;for(auto filepath : m_loaders.keys()){QPluginLoader *loader = m_loaders.value(filepath);PluginInterface *Plugin = dynamic_cast<PluginInterface*>(loader->instance());if(Plugin)str = Plugin->datawrite();}return str;}

插件代碼

#ifndef LOGPLUGIN_H#define LOGPLUGIN_H#include "logPlugin_global.h"#include "../PluginManager/PluginInterface.h"#include <QObject>class LOGPLUGIN_EXPORT LogPlugin: public QObject,public PluginInterface{Q_OBJECTQ_INTERFACES(PluginInterface) ??//聲明這個插件實現是基于哪個插件接口的Q_PLUGIN_METADATA(IID "org.qt-LogPlugin" FILE "LogPlugin.json") ?//使用Q_PLUGIN_METADATA宏導出插件public:LogPlugin();virtual QString datawrite() override;};#endif // LOGPLUGIN_H#ifndef DBPLUGIN_H#define DBPLUGIN_H#include "DbPlugin_global.h"#include "../PluginManager/PluginInterface.h"#include <QObject>class DBPLUGIN_EXPORT DbPlugin : public QObject,public PluginInterface{public: ??Q_OBJECTQ_INTERFACES(PluginInterface) ??//聲明這個插件實現是基于哪個插件接口的Q_PLUGIN_METADATA(IID "org.qt-DbPlugin" FILE "DbPlugin.json") ?//使用Q_PLUGIN_METADATA宏導出插件public:DbPlugin();virtual QString datawrite() override;};#endif // DBPLUGIN_H

App代碼

#include "dialog.h"#include "ui_dialog.h"#include <QDebug>#include <QPluginLoader>#include <QFileInfo>#include <QDir>#include <QPushButton>#include "../PluginManager/pluginmanager.h"Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog){ui->setupUi(this);}Dialog::~Dialog(){delete ui;}void Dialog::on_pushButton_clicked(){PluginManager::getinstance()->loadAllPlugins();PluginManager::getinstance()->datawrite();PluginManager::getinstance()->unloadAllPlugins();}

插件通信

插件的通信通過插件管理器來管理,插件管理器轉發(fā)插件的消息

  1. 在插件管理器的接口頭文件增加一個插件間通信的結構體,增加插件發(fā)送消息和接收消息的純虛函數。

Q_DECLARE_METATYPE(Type)

作用:向Qt元系統(tǒng)注冊一些非基本類型

這個宏能使Qt元系統(tǒng)的QMetaType知道Type類型,但前提是Type類型必須提供一個公有的默認構造函數、公有的默認拷貝構造函數和公有的默認析構函數。

  1. 在插件重寫插件管理器聲明的接收函數插件管理器聲明的發(fā)送函數聲明為信號。

  1. 在插件管理器的加載插件處加上connect函數,是信號槽關聯起來。其中把插件發(fā)送信號關聯插件管理器的接收槽函數。

同時讓插件管理器的接收槽函數轉發(fā)給對應的插件

  1. 在app程序中調用調用插件的信號從而發(fā)送消息

完整代碼參見:

鏈接:https://pan.baidu.com/s/1fWK_oSYQTRNip4FLnTOLwg

提取碼:qc0t

http://www.risenshineclean.com/news/52893.html

相關文章:

  • 專門做干果批發(fā)的網站國際新聞頭條今日國際大事
  • 東莞網站建設推廣公司哪家好如何推廣app賺錢
  • 亞馬遜網官網首頁四川seo平臺
  • 做相冊本哪個網站好用嗎短視頻推廣
  • 制作網站公石家莊谷歌seo
  • 做公司網站需要會什么一鍵優(yōu)化表格
  • 有哪些做微博長圖網站澤成seo網站排名
  • 辦文明網站 做文明網民活動關鍵詞查詢網
  • 網絡推廣文案案例鄭州網站seo優(yōu)化公司
  • wordpress黑桃錘擊河北seo網絡推廣
  • 建設銀行網站查詢密碼怎么開通seo的宗旨是什么
  • 廣州新際網站建設公司怎么樣世界球隊最新排名
  • 泰安網站建設公司seo個人優(yōu)化方案案例
  • 網站開發(fā)得花多少錢營業(yè)推廣是一種什么樣的促銷方式
  • 軟件開發(fā)項目實施方案網站seo服務商
  • php做視頻直播網站信息流廣告投放工作內容
  • 普通的訂閱號怎么做微網站泉州搜索推廣
  • 工程造價材料信息網山東seo推廣
  • 怎么樣創(chuàng)辦一個網站如何在國外推廣自己的網站
  • 專業(yè)酒店設計網站建設廣州網站快速排名
  • 騙子為啥使用香港服務器seo網站管理
  • dw班級網站建設全國疫情最新情況公布
  • jsp網站開發(fā)實例精講seo外包方案
  • 網站空間 php程序谷歌瀏覽器下載手機版中文
  • 網站制作價格 上海百度網頁推廣怎么做
  • poco攝影網win10優(yōu)化大師官網
  • 撤銷網站備案企業(yè)qq手機版
  • 做時時彩網站平臺有哪些淘寶指數查詢工具
  • 建筑模板尺寸關鍵詞優(yōu)化營銷
  • 怎么樣建設一個網站關鍵詞排名優(yōu)化報價