Qt लाइब्रेरी पर एक विस्तार प्रणाली बनाना

प्लगइन्स (एक्सटेंशन)


एक्सटेंशन एक साझा गतिशील लाइब्रेरी है जिसे मुख्य एप्लिकेशन के निष्पादन के दौरान लोड करने के लिए डिज़ाइन किया गया है, जिसे आवश्यक रूप से कम से कम एक विशेष इंटरफ़ेस लागू करना चाहिए।

एक्सटेंशन को दो प्रकारों में विभाजित किया गया है:

  • Qt के लिए
  • देशी अनुप्रयोगों के लिए

आइए जानें कि कैसे अपनी खुद की विस्तार प्रणाली और इसके लिए स्वयं एक्सटेंशन बनाने के लिए।

एक्सटेंशन के साथ संचार इंटरफ़ेस (सिग्नल, स्लॉट और क्लास मेथड) का उपयोग करके किया जाता है। एक्सटेंशन को QPluginLoader वर्ग का उपयोग करके लोड किया जाता है। एक्सटेंशन को लोड करने के लिए , इंस्टेंस () विधि का उपयोग किया जाता है, जो एक एक्सटेंशन ऑब्जेक्ट बनाता है और इसे एक पॉइंटर लौटाता है। एक्सटेंशन को अनलोड करने के लिए अनलोड () विधि का उपयोग किया जाता है।

भाग 1


पहले उदाहरण में, एक एक्सटेंशन बनाएं जो एक्सटेंशन से फ़ंक्शन (एल्गोरिथम, सूत्र) का उपयोग करेगा।

परियोजना की दृश्य योजना निम्नानुसार होगी।



स्टेज 1:


पहला कदम QObject से विरासत में मिला एक इंटरफ़ेस वर्ग बनाना है, एक इंटरफ़ेस के रूप में एक विधि होगी जो टाइप QString का एक चर लेती है और ऊपरी मामले में समान स्ट्रिंग लौटाती है। Q_DECLARE_INTERFACE मैक्रो का उपयोग करते हुए, हम इंटरफेस की पहचानकर्ता सेट करते हैं, कंपाइलर सी पहचानकर्ता स्ट्रिंग के लिए मेटा-जानकारी उत्पन्न करता है। यह मॉड्यूल प्लग-इन और मुख्य कार्यक्रम के बीच संचार प्रोटोकॉल है और इसका उपयोग प्लग-इन प्रोजेक्ट और मुख्य प्रोजेक्ट में किया जाएगा।

वर्ग निम्नानुसार दिखेगा।

//--------------------------------------------------- #ifndef INTERFACE_H #define INTERFACE_H //------------------------------------------------------- #include <QObject> //------------------------------------------------------- class interface : public QObject { public: /// \brief   virtual ~interface() = default; /// \brief   virtual QString getUpString(QString str) = 0; }; //---------------------------------------------------------------- Q_DECLARE_INTERFACE(interface, "com.mysoft.Application.interface") //---------------------------------------------------------------- #endif // INTERFACE_H //---------------------------------------------------------------- 


स्टेज 2:


आइए एक मूल एप्लिकेशन बनाएं जो एक्सटेंशन डाउनलोड करेगा। बटन दबाकर, एक्सटेंशन को खोजा जाएगा और सिस्टम में लोड किया जाएगा। इंटरफ़ेस के माध्यम से हम अपने फ़ंक्शन का उपयोग करेंगे।

आधार आवेदन:

mainproject.h

 //--------------------------------------------------- #ifndef MAINPROJECT_H #define MAINPROJECT_H //------------------------------------------------------- #include <QWidget> #include <QPluginLoader> #include <QDir> #include "interface.h" //------------------------------------------------------- namespace Ui { class mainProject; } //------------------------------------------------------- class mainProject : public QWidget { Q_OBJECT public: /// \brief  explicit mainProject(QWidget *parent = nullptr); /// \brief  ~mainProject(); private slots: /// \brief   void on_searchPlugin_clicked(); /// \brief   void on_getUp_clicked(); private: Ui::mainProject *ui; interface *pluginObject; ///<     }; //------------------------------------------------------- #endif // MAINPROJECT_H //------------------------------------------------------- 

mainproject.cpp

 //--------------------------------------------------- #include "mainproject.h" #include "ui_mainproject.h" //------------------------------------------------------- mainProject::mainProject(QWidget *parent) : QWidget(parent), ui(new Ui::mainProject) { ui->setupUi(this); } //------------------------------------------------------- mainProject::~mainProject() { delete ui; } //------------------------------------------------------- void mainProject::on_searchPlugin_clicked() { QStringList listFiles; QDir dir(QApplication::applicationDirPath() + "/Plugins/"); //      "Plugins" if(dir.exists()) listFiles = dir.entryList(QStringList("*"), QDir::Files); //     for(QString str: listFiles) { QPluginLoader loader(dir.absolutePath() + "/" +str); QObject *pobj = 0; //   pobj = qobject_cast<QObject*>(loader.instance()); if(!pobj) continue; pluginObject = 0; //   pluginObject = qobject_cast<interface *>(pobj); //      if(pluginObject) { ui->label->setText(" "); break; } } } //------------------------------------------------------- void mainProject::on_getUp_clicked() { QString tmp; tmp = ui->lineEdit->text(); //   getUpString() tmp = pluginObject->getUpString(tmp); ui->label_2->setText(tmp); } //------------------------------------------------------- 


स्टेज 3:


एक एक्सटेंशन बनाते हुए, पहली बात यह है कि प्रो फ़ाइल में निर्मित प्रोजेक्ट का प्रकार बदल रहा है, इसके लिए आपको निम्न पंक्ति TEMPLATE = lib जोड़ने की आवश्यकता है, और CONFIG + = प्लगइन एक्सटेंशन के लिए प्रोजेक्ट कॉन्फ़िगरेशन सेट करें।

upperstringplugin.pro

 #------------------------------------------------- # # Project created by QtCreator 2019-04-03T11:35:18 # #------------------------------------------------- QT += core greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = upperStringPlugin TEMPLATE = lib CONFIG += plugin DESTDIR = ../Plugins DEFINES += QT_DEPRECATED_WARNINGS CONFIG += c++11 SOURCES += \ upperstringplugin.cpp HEADERS += \ upperstringplugin.h \ interface.h 

अगला, हम भविष्य के विस्तार के लिए एक वर्ग बनाते हैं, वर्ग को इंटरफेस के वर्ग से विरासत में मिला होना चाहिए। मैक्रो Q_INTERFACES , आपको विस्तार के लिए सभी आवश्यक मेटा जानकारी उत्पन्न करने के लिए कंपाइलर की आवश्यकता है। Q_PLUGIN_METADATA () मैक्रो Qt लाइब्रेरी के एक्सटेंशन और एक्सेस के लिए एंट्री पॉइंट सेट करता है। आपको मेटा-इंफॉर्मेशन (प्रोजेक्ट के रूट में फ़ाइल का होना आवश्यक है) के साथ एक inteface.json फ़ाइल बनाने की आवश्यकता है, हमारे मामले में वहाँ कोई जानकारी नहीं है, इसलिए फ़ाइल में केवल खाली उद्धरण चिह्नों {} लिखें।

upperstringplugin.h

 //--------------------------------------------------- #ifndef UPPERSTRINGPLUGIN_H #define UPPERSTRINGPLUGIN_H //--------------------------------------------------- #include "interface.h" //--------------------------------------------------- class upperStringPlugin : public interface { Q_OBJECT Q_INTERFACES(interface) Q_PLUGIN_METADATA(IID "com.mysoft.Application.interface" FILE "interface.json") public: explicit upperStringPlugin(); ~upperStringPlugin(); // interface interface public: QString getUpString(QString str); }; //--------------------------------------------------- #endif // UPPERSTRINGPLUGIN_H //--------------------------------------------------- 

upperstringplugin.cpp

 //--------------------------------------------------- #include "upperstringplugin.h" //--------------------------------------------------- upperStringPlugin::upperStringPlugin() {} //--------------------------------------------------- upperStringPlugin::~upperStringPlugin() {} //--------------------------------------------------- QString upperStringPlugin::getUpString(QString str) { return str.toUpper(); } //--------------------------------------------------- 

परियोजना को संकलित करने के आउटपुट में, हमें एक्सटेंशन के साथ एक फ़ाइल मिलती है। इस फाइल को मुख्य परियोजना के प्लगइन्स फ़ोल्डर में ले जाएं और इसे शुरू करें। इस स्थिति में, एक्सटेंशन को मुख्य प्रोग्राम में लोड किया जाता है और एकल एक्सटेंशन ऑब्जेक्ट बनाया जाता है। यदि आप उदाहरण () फ़ंक्शन का पुन: उपयोग करने का प्रयास करते हैं, तो फ़ंक्शन पहले से बनाई गई एक्सटेंशन ऑब्जेक्ट पर एक पॉइंटर लौटाएगा।

कार्यक्रम का निष्पादन



भाग २


अपने कार्य को जटिल बनाने के लिए, अब हमें एक विजेट बनने के लिए विस्तार और कई ऐसे विजेट बनाने की क्षमता की आवश्यकता है। मुख्य कार्यक्रम प्लगइन्स से संदेश प्राप्त करेगा और एक प्रतिक्रिया वापस भेजेगा। हम नई परियोजनाओं का निर्माण करेंगे, पहले चरण में हमें दो वर्गों के इंटरफेस की आवश्यकता होगी, एक विस्तार लोड करने और विजेट बनाने के लिए जिम्मेदार होगा, दूसरा विजेट के संचालन के लिए।

परियोजना योजना निम्नानुसार होगी:



स्टेज 1:


पहले इंटरफ़ेस वर्ग में दो कार्य होंगे, प्लगइन का नाम प्राप्त करें और प्लगइन विजेट प्राप्त करें। प्लगइन का नाम सिस्टम में पहचान के लिए संग्रहीत किया जाएगा। हम मुख्य एप्लिकेशन के एमडीआई विंडो में प्लगइन विजेट जोड़ देंगे।

दूसरी श्रेणी स्वयं चित्रमय विजेट है, यह QWidget से विरासत में मिली है, यहां हमने उन कार्यों को निर्दिष्ट किया है जिनकी हमें आवश्यकता है, विजेट एक संदेश प्राप्त करेगा और इसे मुख्य कार्यक्रम में भेज देगा।

interface.h

 //------------------------------------------------------------------------- #ifndef INTERFACE_H #define INTERFACE_H //------------------------------------------------------------------------- #include <QWidget> class QString; //------------------------------------------------------------------------- class interface : public QObject { public: /// \brief  virtual ~interface(){} /// \brief    virtual QString getNamePlugin() = 0; /// \brief    virtual QObject *getPluginWidget() = 0; }; //------------------------------------------------------------------------- class interfaceWidget: public QWidget { public: /// \brief  virtual ~interfaceWidget() = default; signals: /// \brief      virtual void signal_writeText(QString str) = 0; public slots: /// \brief      virtual void slot_getText(QString str) = 0; }; //------------------------------------------------------------------------- Q_DECLARE_INTERFACE(interface, "com.mysoft.Application.interface") //------------------------------------------------------------------------- #endif // INTERFACE_H //------------------------------------------------------------------------- 

स्टेज 2:


मुख्य कार्यक्रम में एक एमडीआई विंडो होती है, जिसमें प्लगइन्स से संदेश प्राप्त करने के लिए एक मुख्य विजेट होता है और अतिरिक्त विंडो जो गतिशील रूप से प्लग इन के रूप में प्रकट होती हैं, कहलाती हैं।

एक प्लगइन विजेट बनाते समय, हम प्लग इन से सिग्नल को स्लॉट से जोड़ते हैं और प्रेषक () फ़ंक्शन का उपयोग करके हम उस प्लगइन को एक पॉइंटर प्राप्त करते हैं जो संदेश भेजते हैं। हम एमडीआई विंडो में बनाए गए विजेट को रखते हैं, और प्लग-इन ऑब्जेक्ट को सिस्टम से अनलोड किया जा सकता है।

mainproject.h

 //------------------------------------------------ #ifndef MAINPROJECT_H #define MAINPROJECT_H //------------------------------------------------ #include <QMainWindow> #include <QDir> #include <QPluginLoader> #include "interface.h" //------------------------------------------------ namespace Ui { class mainProject; } //------------------------------------------------ typedef struct str_plugin { QString namePlugin; ///<   QString dirPlugin; ///<   }TSTR_PLUGIN; //------------------------------------------------ class mainWidget; //------------------------------------------------ class mainProject : public QMainWindow { Q_OBJECT public: explicit mainProject(QWidget *parent = nullptr); ~mainProject(); private slots: void on_action_triggered(); /// \brief    void slot_showPlugin(); /// \brief          void slot_getTextFromPlugin(QString str); private: Ui::mainProject *ui; mainWidget *widget; ///<   QVector<TSTR_PLUGIN > vecPlugin; ///<   }; //------------------------------------------------ #endif // MAINPROJECT_H //------------------------------------------------ 

mainproject.cpp

 //------------------------------------------------ #include "mainproject.h" #include "ui_mainproject.h" #include "mainwidget.h" #include <QMdiSubWindow> //------------------------------------------------ mainProject::mainProject(QWidget *parent) : QMainWindow(parent), ui(new Ui::mainProject) { ui->setupUi(this); QMdiSubWindow *sWPS = new QMdiSubWindow; widget = new mainWidget(); sWPS->setWidget(widget); ui->mdiArea->addSubWindow(sWPS); } //------------------------------------------------ mainProject::~mainProject() { delete ui; } //------------------------------------------------ void mainProject::on_action_triggered() { ui->menu_2->clear(); QStringList listFiles; QDir dir(QApplication::applicationDirPath() + "/Plugins/"); if(dir.exists()) { listFiles = dir.entryList(QStringList("*"), QDir::Files); } for(QString str: listFiles) { QPluginLoader loader(dir.absolutePath() + "/" +str); QObject *pobj = 0; pobj = qobject_cast<QObject*>(loader.instance()); if(!pobj) continue; interface *plW = 0; plW = qobject_cast<interface *>(pobj); if(!plW) continue; QString namePlugin = plW->getNamePlugin(); QAction *action = new QAction(namePlugin); ui->menu_2->addAction(action); connect(action, SIGNAL(triggered()), this, SLOT(slot_showPlugin())); TSTR_PLUGIN plug; plug.namePlugin = namePlugin; plug.dirPlugin = dir.absolutePath() + "/" +str; vecPlugin.push_back(plug); delete plW; } } //------------------------------------------------ void mainProject::slot_showPlugin() { QObject *pobj = sender(); QAction *action = qobject_cast<QAction *>(pobj); QString namePlugin = action->iconText(); for(int i = 0; i < vecPlugin.size(); i++) { if(namePlugin == vecPlugin[i].namePlugin) { QMdiSubWindow *sWPS = new QMdiSubWindow; ui->mdiArea->addSubWindow(sWPS); sWPS->setAttribute(Qt::WA_DeleteOnClose, true); QPluginLoader loader(vecPlugin[i].dirPlugin); QObject *pobj = qobject_cast<QObject*>(loader.instance()); if(!pobj) continue; interface *plW = qobject_cast<interface *>(pobj); if(!plW) continue; QObject *ob = plW->getPluginWidget(); if(!ob) continue; interfaceWidget *interFaceW = dynamic_cast<interfaceWidget *>(ob); if(!interFaceW) continue; sWPS->setWidget(interFaceW); sWPS->show(); QSize size = interFaceW->minimumSize(); size.setHeight(size.height() + 20); size.setWidth(size.width() + 20); sWPS->resize(size); loader.unload(); connect(interFaceW, SIGNAL(signal_writeText(QString)), this, SLOT(slot_getTextFromPlugin(QString))); } } } //------------------------------------------------ void mainProject::slot_getTextFromPlugin(QString str) { //     QObject *pobj = sender(); interfaceWidget *pPlug = dynamic_cast<interfaceWidget *>(pobj); widget->slot_getText("   "); widget→slot_getText(str); widget->slot_getText(" "); widget→slot_getText("------------------------------"); pPlug->slot_getText(" "); } //------------------------------------------------ 

मुख्य विंडो संदेश को स्वीकार करती है और उसे प्रदर्शित करती है।

mainwidget.h

 //---------------------------------------------------------- #ifndef MAINWIDGET_H #define MAINWIDGET_H //---------------------------------------------------------- #include <QWidget> //---------------------------------------------------------- namespace Ui { class mainWidget; } //---------------------------------------------------------- class mainWidget : public QWidget { Q_OBJECT public: explicit mainWidget(QWidget *parent = nullptr); ~mainWidget(); public slots: /// \brief      void slot_getText(QString str); private: Ui::mainWidget *ui; }; //---------------------------------------------------------- #endif // MAINWIDGET_H //---------------------------------------------------------- 

mainwidget.cpp

 //---------------------------------------------------------- #include "mainwidget.h" #include "ui_mainwidget.h" //---------------------------------------------------------- mainWidget::mainWidget(QWidget *parent) : QWidget(parent), ui(new Ui::mainWidget) { ui->setupUi(this); } //---------------------------------------------------------- mainWidget::~mainWidget() { delete ui; } //---------------------------------------------------------- void mainWidget::slot_getText(QString str) { ui->textEdit->append(str); } //---------------------------------------------------------- 

स्टेज 2:


हम एक प्लगइन बनाते हैं, इसका विचार यह है कि यह एक विजेट बनाने के लिए एक कारखाना है।

plugin.h

 //------------------------------------------------- #ifndef PLUGIN_H #define PLUGIN_H //------------------------------------------------- #include "interface.h" #include "texttranferwidget.h" //------------------------------------------------- class plugin : public interface { Q_OBJECT Q_INTERFACES(interface) Q_PLUGIN_METADATA(IID "com.mysoft.Application.interface" FILE "interface.json") public: explicit plugin(); ~plugin(); // interface interface public: /// \brief    QString getNamePlugin(); /// \brief    QObject *getPluginWidget(); }; //------------------------------------------------- #endif // PLUGIN_H //------------------------------------------------- 

plugin.cpp

 //------------------------------------------------- #include "plugin.h" //------------------------------------------------- plugin::plugin() { } //------------------------------------------------- plugin::~plugin() { } //------------------------------------------------- QString plugin::getNamePlugin() { return " 1"; } //------------------------------------------------- QObject *plugin::getPluginWidget() { textTranferWidget *widget = new textTranferWidget(); return qobject_cast<QObject *>(widget); } //------------------------------------------------- 

प्लगइन द्वारा बनाई गई विजेट।

texttranferwidget.h

 //------------------------------------------------------------------- #ifndef TEXTTRANFERWIDGET_H #define TEXTTRANFERWIDGET_H //------------------------------------------------------------------- #include "interface.h" //------------------------------------------------------------------- namespace Ui { class textTranferWidget; } //------------------------------------------------------------------- class textTranferWidget : public interfaceWidget { Q_OBJECT public: /// \brief  explicit textTranferWidget(); /// \brief  ~textTranferWidget(); private: Ui::textTranferWidget *ui; // interfaceWidget interface signals: /// \brief      void signal_writeText(QString str); public slots: /// \brief      void slot_getText(QString str); private slots: void on_pushButton_clicked(); }; //------------------------------------------------------------------- #endif // TEXTTRANFERWIDGET_H //------------------------------------------------------------------- 

texttranferwidget.cpp

 //------------------------------------------------------------------- #include "texttranferwidget.h" #include "ui_texttranferwidget.h" //------------------------------------------------------------------- textTranferWidget::textTranferWidget() : ui(new Ui::textTranferWidget) { ui->setupUi(this); } //------------------------------------------------------------------- textTranferWidget::~textTranferWidget() { delete ui; } //------------------------------------------------------------------- void textTranferWidget::slot_getText(QString str) { ui->textEdit->append(str); } //------------------------------------------------------------------- void textTranferWidget::on_pushButton_clicked() { emit signal_writeText(ui->lineEdit->text()); } //------------------------------------------------------------------- 

मुख्य कार्यक्रम का उत्पादन:

Source: https://habr.com/ru/post/hi448806/


All Articles