GalaPlugin - QtCreator के लिए JS / QML प्लगइन

प्लगइन के QtCreator + 2 मोड पैनल का उपयोग करके पोस्ट को पढ़ने के बाद, मुझे एक प्लगइन बनाने की कोशिश करने का विचार था, जो जावास्क्रिप्ट और QML का उपयोग करके QtCreator की कार्यक्षमता का विस्तार कर सकता है। GalaPlugin प्रोजेक्ट दिखाई दिया है



यहाँ एक छोटा सा डेमो है कि क्या हुआ।







यह कैसे काम करता है



इस प्लगइन के लिए विचार काफी सरल है - आरंभीकरण के दौरान, bool initialize(const QStringList &arguments, QString *errorString)



फंक्शन bool initialize(const QStringList &arguments, QString *errorString)



हम प्लगइन फ़ोल्डर में विशेष "स्क्रिप्ट" प्लगइन्स की तलाश करते हैं। ये * .gala एक्सटेंशन वाली जावास्क्रिप्ट फाइलें हैं, जिनमें निम्नलिखित निर्माण हो सकते हैं:



  1. अनिवार्य फ़ंक्शन initialize()



    , जिसे स्क्रिप्ट लोड करने के तुरंत बाद कहा जाता है।
  2. वैकल्पिक extensionsInitialized()



    फ़ंक्शन, जिसे मुख्य प्लगइन के संगत फ़ंक्शन में कहा जाएगा (जब सभी प्लग लोड किए जाते हैं)।
  3. वैकल्पिक के बारे aboutToShutdown()



    फ़ंक्शन, जिसे aboutToShutdown()



    बंद करने से पहले बुलाया जाएगा।
  4. वैकल्पिक पूर्णांक चर galaPluginOrder



    , जो कि बूट समय पर स्क्रिप्ट प्लगइन्स को पुनः व्यवस्थित करने के लिए उपयोग किया जाता है।
  5. वैकल्पिक बूलियन चर galaPluginDisable



    , जिसके साथ आप स्क्रिप्ट प्लग इन को अनदेखा कर सकते हैं।
  6. वैकल्पिक बूलियन चर galaPluginTrace



    , जो आपको सभी galaPluginTrace



    कॉल (डीबगिंग के लिए उपयोगी) को लॉग करने की अनुमति देता है।


यहाँ एक उदाहरण SaveAllBttn.gala स्क्रिप्ट प्लगइन है जो मोड बार में सेव ऑल बटन जोड़ता है

SaveAllBttn.gala
 var galaPluginOrder = 1; var galaPluginTrace = true; function saveAllAction() { var docs = editorManager.documents(); for (var i = 0; i < docs.length; ++i) { var doc = docs[i]; if (doc.isModified()) { doc.save("", false); } } } function createSaveAllButton() { var bttn = galaAPI.createQObject("QPushButton", modeManager); bttn.flat = true; bttn.text = "Save All"; bttn.focusPolicy = 0; bttn.styleSheet = "QPushButton {color: white; }"; // disable button minimum width bttn.sizePolicy = galaAPI.sizePolicy(13, 0, 1); bttn.clicked.connect(saveAllAction); return bttn; } function initialize() { modeManager.addWidget(createSaveAllButton()); galaAPI.debug("Success initialize"); } function extensionsInitialized() { galaAPI.debug("Success extensionsInitialized"); } function aboutToShutdown() { galaAPI.debug("Success aboutToShutdown"); }
      
      







इसके अलावा, 4 और स्क्रिप्ट प्लगइन्स उपलब्ध हैं:



स्क्रिप्टिंग से QtCreator API का उपयोग करने के लिए, मैंने आवश्यक कक्षाओं (जैसे Core::ICore



, Core::Command



, Core::ActionManager



और अन्य) के आसपास रैपर बनाए। रैपर बनाने की प्रक्रिया लगभग यांत्रिक है: हम एक QObject वंशज वर्ग बनाते हैं, पॉइंटर को क्लास से इसमें QtCreator API से स्टोर करते हैं, और सार्वजनिक स्लॉट सेक्शन में रैपर में स्रोत वर्ग के सभी सार्वजनिक तरीकों को फिर से कॉल करते हैं।



यहाँ एक छोटा सा उदाहरण है:
 class GModeManager : public GWrapper { Q_OBJECT public: GModeManager(QJSEngine* jsEngine) : GWrapper(jsEngine), m_owner(qobject_cast<Core::ModeManager*>(Core::ModeManager::instance())) { Q_ASSERT(m_owner); } ~GModeManager() {} Core::ModeManager* owner1() { return m_owner; } public slots: QJSValue owner() { return m_jsEngine->toScriptValue(m_owner); } QJSValue currentMode() { return m_jsEngine->toScriptValue(m_owner->currentMode()); } QJSValue mode(QString id) { return m_jsEngine->toScriptValue(m_owner->mode(str2id(id))); } void addAction(QAction *action, int priority) { m_owner->addAction(action, priority); } void addProjectSelector(QAction *action) { m_owner->addProjectSelector(action); } void addWidget(QWidget *widget) { m_owner->addWidget(widget); } void activateMode(QString id) { m_owner->activateMode(str2id(id)); } void setFocusToCurrentMode() { m_owner->setFocusToCurrentMode(); } bool isModeSelectorVisible() { return m_owner->isModeSelectorVisible(); } void setModeSelectorVisible(bool visible) { m_owner->setModeSelectorVisible(visible); } private: Core::ModeManager* m_owner; };
      
      







कार्यों के साथ एक छोटी सी जटिलता जो ऑब्जेक्ट्स को पॉइंटर्स की एक सूची लौटाती है: उन्हें जावास्क्रिप्ट ऐरे मूल्यों में पैक करने की आवश्यकता होती है। यहाँ editorManager.documents()



फ़ंक्शन का एक उदाहरण कार्यान्वयन है:



 QJSValue documents() { QList<Core::IDocument *> documents = m_owner->documentModel()->openedDocuments(); QJSValue array = m_jsEngine->newArray(documents.size()); for (quint32 i = 0; i < (quint32)documents.size(); ++i) { array.setProperty(i, m_jsEngine->newQObject(new GDocument(m_jsEngine, documents[i]))); } return array; }
      
      







वर्तमान में, जावास्क्रिप्ट / QML वातावरण में, आप निम्नलिखित वैश्विक वस्तुओं का उपयोग कर सकते हैं:



  1. कोर - Core::ICore::instance()



    प्रतिनिधित्व करता है Core::ICore::instance()



  2. messageManager - Core::MessageManager::instance()



    प्रतिनिधित्व करता है Core::MessageManager::instance()



  3. ActionManager - Core::ActionManager::instance()



    प्रतिनिधित्व करता है Core::ActionManager::instance()



  4. EditorManager - Core::EditorManager:instance()



    परिचय देता है Core::EditorManager:instance()



  5. ModeManager - Core::ModeManager::instance()



    प्रतिनिधित्व करता है Core::ModeManager::instance()



  6. galaAPI - सहायक उपयोगी कार्यों के लिए एक पहुँच बिंदु के रूप में कार्य करता है


प्लगइन लिखते समय, मुझे निम्नलिखित समस्याओं का सामना करना पड़ा।

यदि स्लॉट QObject को विरासत में मिली वस्तु के लिए एक पॉइंटर लौटाता है, तो जावास्क्रिप्ट वातावरण इस ऑब्जेक्ट का स्वामित्व लेता है। यह उपयोगी है अगर स्लॉट एक आवरण बनाता है और इसे जेएस कोड को वापस कर देता है। उदाहरण के लिए



 GCommand *command(QString id) { return new GCommand(m_jsEngine, m_owner->command(str2id(id))); }
      
      





यदि स्लॉट आंतरिक QtCreator ऑब्जेक्ट देता है, तो पर्यावरण को इसका मालिक नहीं होना चाहिए। ऐसे मामलों में, आपको ऑब्जेक्ट को सूचक नहीं, बल्कि एक QJSValue लौटना होगा, जिसमें सूचक को लपेटना है।



 //  QMenu* QJSValue menu() const { return m_jsEngine->toScriptValue(static_cast<QObject*>(m_owner->menu())); }
      
      







जेएस में सिग्नल अग्रेषण के साथ एक और समस्या डिफ़ॉल्ट पैरामीटर और समान विधि नाम है।



जब जेएस से कुछ विधि foo



को बुलाया जाता है, तो उस नाम के साथ एक विधि वस्तु के मेटा-सिस्टम में खोज की जाती है और पहले वाले को कहा जाता है। मापदंडों की संख्या (और, विशेष रूप से, प्रकार) में कोई तुलना नहीं है। इस स्थिति में, यदि संकेत में डिफ़ॉल्ट पैरामीटर हैं, तो moc कई मेटा-विधियाँ उत्पन्न करता है। उदाहरण के लिए, एक संकेत void foo(int a, int b = 0, int c = 1);



तीन मेटा तरीके उत्पन्न किए जाएंगे

 void foo(int a); void foo(int a, int b); void foo(int a, int b, int c);
      
      





और यह इस क्रम में है - पहला सबसे छोटा संस्करण। इसलिए, जेएस में डिफ़ॉल्ट मापदंडों का उपयोग करना संभव नहीं है और आपको सभी मापदंडों को मैन्युअल रूप से पास करना होगा। और उसी नाम के तरीकों को अद्वितीय बनाते हैं।



निष्कर्ष



यह प्लगइन आपको QtCreator'a की कार्यक्षमता को बहुत आसानी से विस्तारित करने की अनुमति देता है। मैं मोड पैनल पर दृश्य तत्वों को बनाने के लिए स्क्रिप्ट प्लग-इन का मुख्य उपयोग देखता हूं, अक्सर उपयोग किए जाने वाले या विशिष्ट आदेशों के लिए टूलबार और मेनू आइटम बनाता हूं। क्यूएमएल वस्तुओं को एम्बेड करने की क्षमता महान अवसर प्रदान करती है। आप आसानी से एक QML दृश्य बना सकते हैं जो किसी भी वेब सेवा की निगरानी करेगा, चाहे वह मौसम हो, विनिमय दर हो, आपके पसंदीदा संसाधन पर नए लेख हों, खेल में खाते हों, निर्माण की स्थिति हो आदि। मैं क्यूएमएल पेशेवर नहीं हूं, लेकिन नेट पर कई दिलचस्प उदाहरण हैं।



यदि आपके पास एक दिलचस्प विचार है या, इससे भी बेहतर, आपने एक दिलचस्प स्क्रिप्ट प्लगइन लागू किया है, तो कृपया समुदाय के साथ साझा करें। मुझे इसे अपने प्रोजेक्ट में शामिल करके खुशी होगी।



मैं विभिन्न प्लेटफार्मों के लिए प्लगइन को संकलित करने में भी मदद मांगता हूं। विंडोज के साथ, परेशानी का निर्माण उतना आसान है जितना कि लिनक्स के साथ होता है। MacOS के तहत, बिल्कुल भी निर्माण करने का कोई तरीका नहीं है।



अंत तक पढ़ने वालों के लिए पीएस, एक और वीडियो:




All Articles