Qt 5.11 - Getting Started Programming with Qt Quick

क्यूटी क्विक के साथ प्रोग्रामिंग शुरू करना




qt

क्यूटी क्विक के साथ प्रोग्रामिंग शुरू करना

घोषित यूआई भाषा, क्यूएमएल की दुनिया में आपका स्वागत है। इस स्टार्टिंग गाइड में, हम QML का उपयोग करके एक साधारण टेक्स्ट एडिटर एप्लिकेशन बनाएंगे। इस गाइड को पढ़ने के बाद, आपको क्यूएमएल और क्यूटी सी ++ का उपयोग करके अपने स्वयं के अनुप्रयोगों को विकसित करने के लिए तैयार होना चाहिए।

उपयोगकर्ता इंटरफेस बनाने के लिए QML

हम जो एप्लिकेशन बना रहे हैं, वह एक साधारण टेक्स्ट एडिटर है जो कुछ टेक्स्ट मैनिपुलेशन को लोड, सेव और सेव करेगा। इस गाइड में दो भाग होंगे। पहले भाग में QML में घोषणात्मक भाषा का उपयोग करते हुए एप्लिकेशन लेआउट और व्यवहार को डिजाइन करना शामिल होगा। दूसरे भाग के लिए, Qt C ++ का उपयोग करके फ़ाइल लोडिंग और सेविंग को लागू किया जाएगा। Qt के मेटा-ऑब्जेक्ट सिस्टम का उपयोग करके, हम C ++ फ़ंक्शन को उन गुणों के रूप में उजागर कर सकते हैं जो QML ऑब्जेक्ट प्रकार का उपयोग कर सकते हैं। QML और Qt C ++ का उपयोग करते हुए, हम एप्लिकेशन लॉजिक से इंटरफ़ेस लॉजिक को कुशलता से कम कर सकते हैं।

पूरा स्रोत कोड examples/quick/tutorials/gettingStartedQml निर्देशिका में है। यदि आप यह देखना चाहते हैं कि अंतिम रूप दिया गया आवेदन कैसा दिखता है, तो आप पाठ संपादक को चलाना छोड़ सकते हैं।

इस ट्यूटोरियल का C ++ भाग मानता है कि पाठक के पास Qt की संकलन प्रक्रियाओं का बुनियादी ज्ञान है।

ट्यूटोरियल अध्याय:

  1. एक बटन और एक मेनू को परिभाषित करना
  2. एक मेनू बार को लागू करना
  3. एक पाठ संपादक का निर्माण
  4. पाठ संपादक को सजाने
  5. Qt C ++ का उपयोग करके QML का विस्तार करना

क्यूएमएल के बारे में जानकारी, जैसे कि वाक्य रचना और विशेषताएं, क्यूएमएल संदर्भ में शामिल हैं

एक बटन और एक मेनू को परिभाषित करना

मूल घटक - एक बटन

हम एक बटन बनाकर अपना टेक्स्ट एडिटर शुरू करते हैं। कार्यात्मक रूप से, एक बटन में एक माउस संवेदनशील क्षेत्र और एक लेबल होता है। उपयोगकर्ता द्वारा बटन दबाने पर बटन क्रिया करते हैं।

QML में, मूल दृश्य आइटम Rectangle प्रकार है। Rectangle QML वस्तु प्रकार में QML गुण होते हैं जो इसकी उपस्थिति और स्थान को नियंत्रित करते हैं।

import QtQuick 2.3

Rectangle {
    id: simpleButton
    color: "grey"
    width: 150; height: 75

    Text {
        id: buttonLabel
        anchors.centerIn: parent
        text: "button label"
    }
}

सबसे पहले, import QtQuick 2.3 कथन QML प्रकार के QML प्रकारों को आयात करने की अनुमति देता है qmlscene हम बाद में उपयोग करेंगे। यह पंक्ति प्रत्येक QML फ़ाइल के लिए मौजूद होनी चाहिए। ध्यान दें कि Qt मॉड्यूल का संस्करण आयात विवरण में शामिल है।

इस सरल आयत में एक विशिष्ट पहचानकर्ता, simpleButton , जो id संपत्ति से जुड़ा है। Rectangle वस्तु के गुण संपत्ति को सूचीबद्ध करके मूल्यों के लिए बाध्य हैं, इसके बाद एक बृहदान्त्र, फिर मूल्य। कोड नमूने में, रंग grey रेक्टेंगल की color संपत्ति के लिए बाध्य है। इसी तरह, हम आयत की width और height को बांधते हैं।

Text प्रकार एक गैर-संपादन योग्य पाठ फ़ील्ड है। हम इस ऑब्जेक्ट buttonLabel नाम buttonLabel । टेक्स्ट फ़ील्ड की स्ट्रिंग सामग्री सेट करने के लिए, हम text प्रॉपर्टी के लिए एक मूल्य बाँधते हैं। लेबल आयत के भीतर समाहित है और बीच में इसे केंद्र में रखने के लिए, हम टेक्स्ट ऑब्जेक्ट के anchors को उसके अभिभावक को सौंप देते हैं, जिसे simpleButton कहा जाता है। एंकर अन्य वस्तुओं के लंगर के लिए बाध्य हो सकते हैं, लेआउट असाइनमेंट को सरल बनाने की अनुमति देते हैं।

हम इस कोड को SimpleButton.qml के रूप में SimpleButton.qml । फ़ाइल के साथ qmlscene चल रहा है क्योंकि तर्क पाठ लेबल के साथ ग्रे आयत प्रदर्शित करेगा।

बटन क्लिक कार्यक्षमता को लागू करने के लिए, हम QML के ईवेंट हैंडलिंग का उपयोग कर सकते हैं। क्यूएमएल का ईवेंट हैंडलिंग क्यूटी के सिग्नल और स्लॉट तंत्र के समान है। सिग्नल उत्सर्जित होते हैं और जुड़ा हुआ स्लॉट कहा जाता है।

Rectangle {
    id: simpleButton
    ...

    MouseArea {
        id: buttonMouseArea

        // Anchor all sides of the mouse area to the rectangle's anchors
        anchors.fill: parent
        // onClicked handles valid mouse button clicks
        onClicked: console.log(buttonLabel.text + " clicked")
    }
}

हम अपने MouseArea में एक MouseArea ऑब्जेक्ट शामिल करते हैं। MouseArea ऑब्जेक्ट्स उस इंटरएक्टिव क्षेत्र का वर्णन करते हैं जहां माउस की चाल का पता लगाया जाता है। हमारे बटन के लिए, हम पूरे MouseArea को उसके अभिभावक के लिए लंगर देते हैं, जो कि simpleButtonanchors.fill सिंटैक्स एक विशिष्ट संपत्ति तक पहुंचने का एक तरीका है जिसे anchors नामक संपत्तियों के समूह के अंदर fill है। QML लंगर-आधारित लेआउट का उपयोग करता है जहां आइटम किसी अन्य आइटम के लिए लंगर डाल सकते हैं, जिससे मजबूत लेआउट बनते हैं।

MouseArea में कई सिग्नल हैंडलर होते हैं, जिन्हें निर्दिष्ट MouseArea सीमाओं के भीतर माउस आंदोलनों के दौरान कहा जाता है। उनमें से एक onClicked और इसे जब भी स्वीकार्य माउस बटन क्लिक किया जाता है, बायाँ डिफ़ॉल्ट कहा जाता है। हम ऑनक्लुक हैंडलर पर कार्रवाई कर सकते हैं। जब भी माउस क्षेत्र पर क्लिक किया जाता है, तो हमारे उदाहरण में, console.log() टेक्स्ट को आउटपुट करता है। फ़ंक्शन console.log() डिबगिंग उद्देश्यों के लिए और पाठ के आउटपुट के लिए एक उपयोगी उपकरण है।

SimpleButton.qml का कोड जब भी माउस से क्लिक किया जाता है तो स्क्रीन और आउटपुट टेक्स्ट पर एक बटन को प्रदर्शित करने के लिए पर्याप्त होता है।

Rectangle {
    id: button
    ...

    property color buttonColor: "lightblue"
    property color onHoverColor: "gold"
    property color borderColor: "white"

    signal buttonClick()

    onButtonClick: {
        console.log(buttonLabel.text + " clicked")
    }

    MouseArea{
        id: buttonMouseArea
        onClicked: buttonClick()
        hoverEnabled: true
        onEntered: parent.border.color = onHoverColor
        onExited:  parent.border.color = borderColor
    }

    // Determines the color of the button by using the conditional operator
    color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor
}

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

कस्टम गुण गुण property type name सिंटैक्स का उपयोग करके घोषित किए जाते हैं। कोड में, टाइप buttonColor का प्रॉपर्टी buttonColor , घोषित किया गया है और मूल्य "lightblue" लिए बाध्य है। बटन का रंग बाद में बटन के रंग को निर्धारित करने के लिए एक सशर्त संचालन में उपयोग किया जाता है। ध्यान दें कि : कॉलन वर्ण का उपयोग करके मान बाइंडिंग के अलावा, = बराबर चिह्न का उपयोग करके गुण मान असाइनमेंट संभव है। कस्टम गुण आंतरिक वस्तुओं को आयत के दायरे से बाहर सुलभ होने की अनुमति देते हैं। बुनियादी क्यूएमएल प्रकार हैं जैसे int , string , real , साथ ही एक प्रकार जिसे variant कहा जाता variant

onEntered और onExited सिग्नल हैंडलर को रंगों से onExited से, बटन की सीमा पीले रंग में बदल जाएगी जब माउस बटन के ऊपर onEntered और माउस क्षेत्र से बाहर निकलने पर रंग को बदल देता है।

सिग्नल नाम के सामने signal कीवर्ड लगाकर Button.qml में एक Button.qml buttonClick() सिग्नल घोषित किया Button.qml है। सभी सिग्नल अपने हैंडलर स्वचालित रूप से बनाए जाते हैं, उनके नाम शुरू होते on । नतीजतन, onButtonClick करने onButtonClick है। onButtonClick को प्रदर्शन करने के लिए एक क्रिया सौंपी onButtonClick है। हमारे बटन उदाहरण में, onClicked माउस हैंडलर बस onButtonClick कॉल onButtonClick , जो एक टेक्स्ट प्रदर्शित करता है। onButtonClick बाहरी वस्तुओं को Button के माउस क्षेत्र तक आसानी से पहुंचने में सक्षम बनाता है। उदाहरण के लिए, आइटम में एक से अधिक MouseArea घोषणाएं हो सकती हैं और एक MouseArea MouseArea संकेत कई MouseArea सिग्नल संचालकों के बीच अंतर को बेहतर बना सकता है।

अब हमारे पास QML में आइटम को लागू करने के लिए बुनियादी ज्ञान है जो बुनियादी माउस आंदोलनों को संभाल सकता है। हमने एक Rectangle अंदर एक Text लेबल बनाया, उसके गुणों को अनुकूलित किया और उन व्यवहारों को कार्यान्वित किया जो माउस की चाल पर प्रतिक्रिया करते हैं। वस्तुओं के भीतर QML ऑब्जेक्ट बनाने का यह विचार पूरे टेक्स्ट एडिटर एप्लिकेशन में दोहराया जाता है।

जब तक किसी क्रिया को करने के लिए घटक के रूप में उपयोग नहीं किया जाता है तब तक यह बटन उपयोगी नहीं है। अगले भाग में, हम जल्द ही इनमें से कई बटनों वाला एक मेनू बनाएंगे।

मेनू पेज बनाना

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

मेनू एक सूची की सामग्री को प्रदर्शित करता है, प्रत्येक आइटम में एक क्रिया करने की क्षमता होती है। QML में, हम कई तरीकों से एक मेनू बना सकते हैं। सबसे पहले, हम एक मेनू बनाएंगे जिसमें बटन होंगे जो अंत में विभिन्न क्रियाएं करेंगे। मेनू कोड FileMenu.qml

import QtQuick 2.3             // Import the main Qt QML module
import "folderName"            // import the contents of a folder
import "script.js" as Script   // Import a Javascript file and name it as Script

ऊपर दिखाया गया सिंटैक्स दिखाता है कि import कीवर्ड का उपयोग कैसे किया जाए। इसके लिए जावास्क्रिप्ट फ़ाइलों, या QML फ़ाइलों का उपयोग करना आवश्यक है जो समान निर्देशिका में नहीं हैं। चूंकि Button.qml उसी निर्देशिका में FileMenu.qml रूप में है, इसलिए हमें इसका उपयोग करने के लिए Button.qml फ़ाइल को आयात करने की आवश्यकता नहीं है। हम सीधे Rectangle{} घोषणा के समान Button{} घोषणा करके एक Button ऑब्जेक्ट बना सकते हैं।

In FileMenu.qml:

    Row {
        anchors.centerIn: parent
        spacing: parent.width / 6

        Button {
            id: loadButton
            buttonColor: "lightgrey"
            label: "Load"
        }
        Button {
            buttonColor: "grey"
            id: saveButton
            label: "Save"
        }
        Button {
            id: exitButton
            label: "Exit"
            buttonColor: "darkgrey"

            onButtonClick: Qt.quit()
        }
    }

FileMenu.qml , हम तीन Button ऑब्जेक्ट घोषित करते हैं। उन्हें Row प्रकार के अंदर घोषित किया जाता है, एक पोजिशनर जो अपने बच्चों को एक ऊर्ध्वाधर पंक्ति के साथ स्थिति देगा। Button घोषणापत्र Button.qml में रहता है, जो पिछले अनुभाग में हमारे द्वारा उपयोग किए जाने के समान है। नई प्रॉपर्टी बाइंडिंग को नए बनाए गए बटनों के भीतर घोषित किया जा सकता है, प्रभावी रूप से Button.qml में सेट की गई संपत्तियों को अधिलेखित कर सकते हैं। exitButton बटन बटन को क्लिक करने पर विंडो बंद हो जाएगी और बंद हो जाएगी। ध्यान दें कि onButtonClick में Button.qml सिग्नल हैंडलर को onButtonClick में Button.qml हैंडलर के अलावा कहा जाएगा।

Row घोषणा एक Rectangle , जो बटन की पंक्ति के लिए एक आयत कंटेनर बनाती है। यह अतिरिक्त आयत एक मेनू के अंदर बटन की पंक्ति को व्यवस्थित करने का एक अप्रत्यक्ष तरीका बनाता है।

इस स्तर पर संपादन मेनू की घोषणा बहुत समान है। मेनू में बटन होते हैं जिनमें लेबल होते हैं: Copy , Paste , और Select All

पहले से बनाए गए घटकों को आयात और कस्टमाइज़ करने के हमारे ज्ञान के साथ सशस्त्र, हम अब मेनू मेनू का चयन करने के लिए बटन से मिलकर मेनू बार बनाने के लिए इन मेनू पृष्ठों को जोड़ सकते हैं, और देख सकते हैं कि हम QML का उपयोग करके डेटा को कैसे संरचना कर सकते हैं।

एक मेनू बार को लागू करना

हमारे टेक्स्ट एडिटर एप्लिकेशन को मेनू बार का उपयोग करके मेनू प्रदर्शित करने के तरीके की आवश्यकता होगी। मेनू बार अलग-अलग मेनू को स्विच करेगा और उपयोगकर्ता चुन सकता है कि कौन सा मेनू प्रदर्शित करना है। मेनू स्विचिंग का अर्थ है कि मेनू को केवल एक पंक्ति में प्रदर्शित करने की तुलना में अधिक संरचना की आवश्यकता है। QML डेटा को संरचना करने और संरचित डेटा प्रदर्शित करने के लिए मॉडल और दृश्यों का उपयोग करता है।

डेटा मॉडल और दृश्य का उपयोग करना

क्यूएमएल में विभिन्न डेटा दृश्य होते हैं जो डेटा मॉडल प्रदर्शित करते हैं । हमारा मेनू बार सूची में मेनू प्रदर्शित करेगा, एक हेडर के साथ जो मेनू नामों की एक पंक्ति प्रदर्शित करता है। ObjectModel अंदर मेनू की सूची घोषित की ObjectModelObjectModel प्रकार में ऐसी वस्तुएँ होती हैं जो पहले से ही डिस्प्ले करने योग्य होती हैं, जैसे कि Rectangle वस्तुएँ। अन्य मॉडल प्रकार, जैसे ListModel प्रकार, को अपना डेटा प्रदर्शित करने के लिए एक प्रतिनिधि की आवश्यकता होती है।

हम menuListModel , FileMenu और menuListModel में दो दृश्य आइटम घोषित करते हैं। हम दो मेनू को कस्टमाइज़ करते हैं और उन्हें एक ListView में प्रदर्शित करते हैं। MenuBar.qml फ़ाइल में QML घोषणाएँ हैं और एक सरल संपादन मेनू EditMenu.qml में परिभाषित किया EditMenu.qml

ObjectModel {
    id: menuListModel

    FileMenu {
        width: menuListView.width
        height: menuBar.height
        color: fileColor
    }

    EditMenu {
        color: editColor
        width: menuListView.width
        height: menuBar.height
    }
}

ListView प्रकार एक प्रतिनिधि के अनुसार एक मॉडल प्रदर्शित करेगा। प्रतिनिधि एक Row वस्तु या एक ग्रिड में मॉडल आइटम प्रदर्शित कर सकता है। हमारे menuListModel पहले से ही दृश्यमान वस्तुएं हैं, इसलिए, हमें एक प्रतिनिधि घोषित करने की आवश्यकता नहीं है।

ListView {
    id: menuListView

    // Anchors are set to react to window anchors
    anchors.fill: parent
    anchors.bottom: parent.bottom
    width: parent.width
    height: parent.height

    // The model contains the data
    model: menuListModel

    // Control the movement of the menu switching
    snapMode: ListView.SnapOneItem
    orientation: ListView.Horizontal
    boundsBehavior: Flickable.StopAtBounds
    flickDeceleration: 5000
    highlightFollowsCurrentItem: true
    highlightMoveDuration: 240
    highlightRangeMode: ListView.StrictlyEnforceRange
}

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

ListView index माध्यम से मॉडल आइटम को बनाए रखता है और मॉडल के प्रत्येक दृश्य आइटम index माध्यम से घोषणा के क्रम में सुलभ है। currentIndex बदलना प्रभावी रूप से हाइलाइट किए गए आइटम को ListView में बदलता है। हमारे मेन्यू बार का हेडर इस प्रभाव का उदाहरण देता है। एक पंक्ति में दो बटन होते हैं, दोनों क्लिक करने पर वर्तमान मेनू को बदलते हैं। fileButton क्लिक करने पर वर्तमान मेनू को फ़ाइल मेनू में बदल देता है, index 0 हो रहा है क्योंकि FileMenu मेनू में सबसे पहले घोषित किया गया है। इसी तरह, EditMenu क्लिक करने पर वर्तमान मेनू को editButton में बदल देगा।

labelList आयत का z मान 1 , यह दर्शाते हुए कि यह मेनू बार के सामने प्रदर्शित किया गया है। उच्च z मान वाले आइटम निचले z मान वाले आइटम के सामने प्रदर्शित किए जाते हैं। डिफ़ॉल्ट z मान 0

Rectangle {
    id: labelList
    ...
    z: 1

    Row {
        anchors.centerIn: parent
        spacing: 40

        Button {
            label: "File"
            id: fileButton
            ...
            onButtonClick: menuListView.currentIndex = 0
        }

        Button {
            id: editButton
            label: "Edit"
            ...
            onButtonClick: menuListView.currentIndex = 1
        }
    }
}

हमारे द्वारा अभी बनाया गया मेनू बार मेनू पर या शीर्ष पर मेनू नामों पर क्लिक करके उपयोग किया जा सकता है। मेनू स्क्रीन स्विच करना सहज और उत्तरदायी लगता है।

एक पाठ संपादक का निर्माण

एक TextArea की घोषणा

यदि कोई संपादन योग्य पाठ क्षेत्र नहीं है, तो हमारा पाठ संपादक पाठ संपादक नहीं है। QML का TextEdit प्रकार एक बहु-पंक्ति संपादन योग्य पाठ क्षेत्र की घोषणा की अनुमति देता है। TextEdit Text प्रकार से अलग है, जो उपयोगकर्ता को पाठ को सीधे संपादित करने की अनुमति नहीं देता है।

TextEdit {
    id: textEditor
    anchors.fill: parent
    width: parent.width
    height: parent.height
    color: "midnightblue"
    focus: true

    wrapMode: TextEdit.Wrap

    onCursorRectangleChanged: flickArea.ensureVisible(cursorRectangle)
}

एडिटर के पास टेक्स्ट को रैप करने के लिए अपनी फॉन्ट color प्रॉपर्टी सेट और wrapMode सेट है। TextEdit क्षेत्र एक झिलमिलाहट आइटम के अंदर है जो पाठ को स्क्रॉल करेगा यदि पाठ कर्सर दृश्य क्षेत्र के बाहर है। फ़ंक्शन ensureVisible() करें कि ensureVisible() चेक करेगा कि कर्सर आयत दृश्य सीमाओं के बाहर है और तदनुसार पाठ क्षेत्र को स्थानांतरित करें। QML अपनी स्क्रिप्ट्स के लिए जावास्क्रिप्ट सिंटैक्स का उपयोग करता है, और जैसा कि पहले बताया गया है, जावास्क्रिप्ट फ़ाइलों को एक QML फ़ाइल के भीतर आयात और उपयोग किया जा सकता है।

function ensureVisible(r) {
    if (contentX >= r.x)
        contentX = r.x;
    else if (contentX + width <= r.x + r.width)
        contentX = r.x + r.width - width;
    if (contentY >= r.y)
        contentY = r.y;
    else if (contentY + height <= r.y + r.height)
        contentY = r.y + r.height - height;
}

पाठ संपादक के लिए संयोजन घटक

अब हम QML का उपयोग करके अपने टेक्स्ट एडिटर का लेआउट बनाने के लिए तैयार हैं। टेक्स्ट एडिटर में दो घटक होते हैं, मेनू बार हमने बनाया और टेक्स्ट क्षेत्र। क्यूएमएल हमें घटकों का पुन: उपयोग करने की अनुमति देता है, इसलिए घटकों को आयात करके और आवश्यक होने पर अनुकूलित करके हमारे कोड को सरल बनाता है। हमारा पाठ संपादक खिड़की को दो में विभाजित करता है; स्क्रीन का एक-तिहाई मेनू बार के लिए समर्पित है और स्क्रीन का दो-तिहाई पाठ क्षेत्र प्रदर्शित करता है। मेनू बार को किसी अन्य ऑब्जेक्ट के सामने प्रदर्शित किया जाता है।

Rectangle {
    id: screen
    width: 1000
    height: 1000

    // The screen is partitioned into the MenuBar and TextArea.
    // One-third of the screen is assigned to the MenuBar
    property int partition: height / 3

    MenuBar {
        id: menuBar
        height: partition
        width: parent.width
        z: 1
    }

    TextArea {
        id: textArea
        anchors.bottom: parent.bottom
        y: partition
        color: "white"
        width: parent.width
        height: partition * 2
    }
}

पुन: प्रयोज्य घटकों को आयात करने से, हमारा TextEditor कोड बहुत सरल दिखता है। हम पहले से परिभाषित व्यवहार वाले गुणों के बारे में चिंता किए बिना, मुख्य एप्लिकेशन को कस्टमाइज़ कर सकते हैं। इस दृष्टिकोण का उपयोग करके, एप्लिकेशन लेआउट और UI घटक आसानी से बनाए जा सकते हैं।

पाठ संपादक को सजाने

एक दराज इंटरफ़ेस लागू करना

हमारा पाठ संपादक सरल दिखता है और हमें इसे सजाने की आवश्यकता है। QML का उपयोग करके, हम संक्रमणों की घोषणा कर सकते हैं और हमारे पाठ संपादक को चेतन कर सकते हैं। हमारा मेनू बार स्क्रीन के एक-तिहाई हिस्से पर कब्जा कर रहा है और यह अच्छा होगा कि यह केवल तब दिखाई दे जब हम इसे चाहते हैं।

हम एक दराज इंटरफ़ेस जोड़ सकते हैं, जो क्लिक करने पर मेनू बार को अनुबंधित या विस्तारित करेगा। हमारे कार्यान्वयन में, हमारे पास एक पतली आयत है जो माउस क्लिक का जवाब देती है। drawer , साथ ही आवेदन में दो संप्रदाय हैं: "दराज खुला है" राज्य और "दराज बंद है" राज्य। drawer आइटम एक छोटी ऊंचाई के साथ आयत की एक पट्टी है। एक नेस्टेड Image ऑब्जेक्ट है जो घोषणा करता है कि एक तीर आइकन ड्रॉअर के अंदर केंद्रित होगा। जब भी कोई उपयोगकर्ता माउस क्षेत्र पर क्लिक करता है, तो वह पहचानकर्ता screen साथ पूरे एप्लिकेशन को एक राज्य प्रदान करता है।

Rectangle {
    id: drawer
    height: 15

    Image {
        id: arrowIcon
        source: "images/arrow.png"
        anchors.horizontalCenter: parent.horizontalCenter
    }

    MouseArea {
        id: drawerMouseArea
        anchors.fill: parent

        onClicked: {
            if (screen.state == "DRAWER_CLOSED")
                screen.state = "DRAWER_OPEN"
            else if (screen.state == "DRAWER_OPEN")
                screen.state = "DRAWER_CLOSED"
        }
        ...
    }
}

एक राज्य केवल विन्यास का एक संग्रह है और इसे State प्रकार के साथ घोषित किया जाता है। राज्यों की सूची को सूचीबद्ध किया जा सकता है और states संपत्ति के लिए बाध्य किया जा सकता है। हमारे आवेदन में, दो राज्यों को DRAWER_CLOSED और DRAWER_OPEN कहा जाता है। PropertyChanges ऑब्जेक्ट में आइटम कॉन्फ़िगरेशन घोषित किए जाते हैं। DRAWER_OPEN राज्य में, चार आइटम हैं जो संपत्ति परिवर्तन प्राप्त करेंगे। पहला लक्ष्य, menuBar , अपनी y संपत्ति को 0 बदल देगा। इसी प्रकार, राज्य textArea पर textArea एक नई स्थिति में कम हो जाएगा। textArea , drawer , और दराज के आइकन वर्तमान स्थिति को पूरा करने के लिए संपत्ति परिवर्तन से गुजरना होगा।

states:[
    State {
        name: "DRAWER_OPEN"
        PropertyChanges { target: menuBar; y: 0 }
        PropertyChanges { target: textArea; y: partition + drawer.height }
        PropertyChanges { target: drawer; y: partition }
        PropertyChanges { target: arrowIcon; rotation: 180 }
    },
    State {
        name: "DRAWER_CLOSED"
        PropertyChanges { target: menuBar; y: -height; }
        PropertyChanges { target: textArea; y: drawer.height; height: screen.height - drawer.height }
        PropertyChanges { target: drawer; y: 0 }
        PropertyChanges { target: arrowIcon; rotation: 0 }
    }
]

राज्य परिवर्तन अचानक होते हैं और चिकनी बदलाव की जरूरत है। राज्यों के बीच संक्रमण को Transition प्रकार का उपयोग करके परिभाषित किया जाता है, जो तब आइटम के transitions संपत्ति के लिए बाध्य हो सकता है। जब भी राज्य DRAWER_OPEN या DRAWER_CLOSED परिवर्तित होता है, तो हमारे पाठ संपादक में एक राज्य परिवर्तन होता है। महत्वपूर्ण रूप से, संक्रमण को एक और एक राज्य की आवश्यकता होती है लेकिन हमारे संक्रमणों के लिए, हम वाइल्ड कार्ड * प्रतीक का उपयोग यह दर्शाने के लिए कर सकते हैं कि संक्रमण सभी राज्य परिवर्तनों पर लागू होता है।

संक्रमण के दौरान, हम संपत्ति परिवर्तनों के लिए एनिमेशन असाइन कर सकते हैं। हमारा menuBar y: 0 से y: -partition स्थिति y: -partition और हम NumberAnimation प्रकार का उपयोग करके इस संक्रमण को चेतन कर सकते हैं। हम घोषणा करते हैं कि निश्चित समय के लिए और एक निश्चित सहजता वक्र का उपयोग करके लक्ष्य के गुण चेतन होंगे। एक सहजता वक्र अवस्थाओं के दौरान एनीमेशन दर और प्रक्षेप व्यवहार को नियंत्रित करता है। हमने जिस सहजता से वक्र को चुना, वह है Easing.OutExpo , जो एनीमेशन के अंत के पास गति को धीमा कर देता है। अधिक जानकारी के लिए, QML का animation लेख देखें।

transitions: [
    Transition {
        to: "*"
        NumberAnimation { target: textArea; properties: "y, height"; duration: 100; easing.type:Easing.OutExpo }
        NumberAnimation { target: menuBar; properties: "y"; duration: 100; easing.type: Easing.OutExpo }
        NumberAnimation { target: drawer; properties: "y"; duration: 100; easing.type: Easing.OutExpo }
    }
]

संपत्ति के प्रकार को बदलने का एक और तरीका Behavior प्रकार की घोषणा करके है। एक संक्रमण केवल राज्य परिवर्तनों के दौरान काम करता है और Behavior सामान्य संपत्ति परिवर्तन के लिए एक एनीमेशन सेट कर सकता है। टेक्स्ट एडिटर में, एरो के पास NumberAnimation होता है, जब भी प्रॉपर्टी बदलती है, तो वह अपनी rotation प्रॉपर्टी को एनिमेट करती है।

TextEditor.qml :

Behavior {
    NumberAnimation { property: "rotation"; easing.type: Easing.OutExpo }
}

राज्यों और एनिमेशन के ज्ञान के साथ अपने घटकों पर वापस जा रहे हैं, हम घटकों की उपस्थिति में सुधार कर सकते हैं। Button.qml , बटन क्लिक करने पर हम color और scale गुण परिवर्तन जोड़ सकते हैं। ColorAnimation का उपयोग करके रंग प्रकार एनिमेटेड हैं और ColorAnimation का उपयोग करके नंबर एनिमेटेड हैं। on propertyName सिनेमैक्स on propertyName नीचे प्रदर्शित एकल संपत्ति को लक्षित करते समय सहायक है।

Button.qml :

...

color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor
Behavior on color { ColorAnimation{ duration: 55 } }

scale: buttonMouseArea.pressed ? 1.1 : 1.0
Behavior on scale { NumberAnimation{ duration: 55 } }

इसके अतिरिक्त, हम अपने क्यूएमएल घटकों के दिखावे को बढ़ा सकते हैं जैसे कि रंग प्रभाव जैसे कि ढाल और अपारदर्शिता प्रभाव। Gradient ऑब्जेक्ट घोषित करने से color संपत्ति ओवरराइड हो जाएगी। आप GradientStop प्रकार का उपयोग करके ढाल में एक रंग की घोषणा कर सकते हैं। ढाल 0.0 और 1.0 बीच एक पैमाने का उपयोग करके तैनात है।

MenuBar.qml :

gradient: Gradient {
    GradientStop { position: 0.0; color: "#8C8F8C" }
    GradientStop { position: 0.17; color: "#6A6D6A" }
    GradientStop { position: 0.98; color: "#3F3F3F" }
    GradientStop { position: 1.0; color: "#0e1B20" }
}

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

यहाँ से कहाँ जाएं

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

Qt C ++ का उपयोग करके QML का विस्तार करना

अब जब हमारे पास हमारा टेक्स्ट एडिटर लेआउट है, तो अब हम C ++ में टेक्स्ट एडिटर फंक्शन्स को लागू कर सकते हैं। C ++ के साथ QML का उपयोग करना हमें Qt का उपयोग करके हमारे एप्लिकेशन लॉजिक को बनाने में सक्षम बनाता है। हम Qt की क्विक क्लासेस का उपयोग करके C ++ एप्लिकेशन में QML संदर्भ बना सकते हैं और QQuickView का उपयोग करके QML प्रकार प्रदर्शित कर QQuickView । वैकल्पिक रूप से, हम अपने C ++ कोड को एक एक्सटेंशन प्लगइन में निर्यात कर सकते हैं, और QML को नए पहचाने गए मॉड्यूल के रूप में सुलभ बना सकते हैं। QMLscene के साथ QML फ़ाइलों को लॉन्च करते qmlscene , हमें केवल यह सुनिश्चित करने की आवश्यकता होती है कि आयात किए गए मॉड्यूल के लिए QML इंजन खोजों में से एक आयात पथ के तहत हमारे मॉड्यूल को मिल जाए। हमारे आवेदन के लिए हम बाद के दृष्टिकोण का उपयोग करेंगे। इस तरह, हम QML फ़ाइल को सीधे निष्पादन योग्य चलाने के बजाय qmlscene साथ लोड कर सकते हैं।

C ++ क्लास को QML में एक्सपोज़ करना

हम Qt और C ++ का उपयोग करके फ़ाइल लोडिंग और बचत को लागू करेंगे। C ++ क्लासेज और फंक्शन्स को QML में रजिस्टर करके इस्तेमाल किया जा सकता है। उन्हें क्यूटी प्लगइन के रूप में भी संकलित करने की आवश्यकता है और फिर एक क्यूएमएल मॉड्यूल के रूप में उजागर किया गया है।

हमारे आवेदन के लिए, हमें निम्नलिखित आइटम बनाने की आवश्यकता है:

  1. Directory वर्ग जो निर्देशिका संबंधी कार्यों को संभालेगा
  2. File क्लास जो एक QObject , एक डायरेक्टरी में फाइलों की सूची का अनुकरण करता है
  3. एक प्लगइन वर्ग जो क्यूएमएल संदर्भ में कक्षाओं को पंजीकृत करेगा
  4. Qt प्रोजेक्ट फ़ाइल जो प्लगइन को संकलित करेगी
  5. एक मॉड्यूल परिभाषा qmldir फ़ाइल जो पहचानकर्ता (आयात URI) और सामग्री (इस मामले में, हमारे प्लगइन) को QML मॉड्यूल द्वारा उपलब्ध कराने को परिभाषित करती है

नोट: क्यूटी 5.1 के बाद से, क्यूटी क्विक डायलॉग मॉड्यूल एक फ़ाइल डायलॉग घटक प्रदान करता है जिसका उपयोग आप स्थानीय फाइल सिस्टम से फाइल चुनने के लिए कर सकते हैं। उदाहरण के लिए, हम इस ट्यूटोरियल में अपना स्वयं का लिखते हैं।

एक Qt प्लगइन का निर्माण

प्लगइन बनाने के लिए, हमें Qt प्रोजेक्ट फ़ाइल में निम्नलिखित सेट करने की आवश्यकता है। सबसे पहले, आवश्यक स्रोतों, हेडर, और क्यूटी मॉड्यूल को हमारी परियोजना फ़ाइल में जोड़ा जाना चाहिए। सभी C ++ कोड और प्रोजेक्ट फाइलें फाइल की filedialog डायरेक्टरी में हैं।

filedialog.pro :

TEMPLATE = lib
CONFIG += qt plugin
QT += qml

DESTDIR +=  ../imports/FileDialog
OBJECTS_DIR = tmp
MOC_DIR = tmp

TARGET = filedialogplugin

HEADERS += \
        directory.h \
        file.h \
        dialogPlugin.h

SOURCES += \
        directory.cpp \
        file.cpp \
        dialogPlugin.cpp

विशेष रूप से, हम प्रोजेक्ट को qml मॉड्यूल के साथ qml और इसे एक plugin रूप में कॉन्फ़िगर करते हैं, एक qml टेम्पलेट का उपयोग करके। हम माता-पिता के imports/FileDialog निर्देशिका में संकलित प्लगइन डालेंगे।

क्यूएमएल में एक कक्षा का पंजीकरण

dialogPlugin.h :

#include <QtQml/QQmlExtensionPlugin>

class DialogPlugin : public QQmlExtensionPlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.QmlExtensionPlugin.FileDialog")

public:
    // registerTypes is inherited from QQmlExtensionPlugin
    void registerTypes(const char *uri);
};

हमें Q_PLUGIN_METADATA मैक्रो का उपयोग करके प्लगइन को निर्यात करने की आवश्यकता है। ध्यान दें कि हमारे dialogPlugin.h फ़ाइल में, हमारे पास हमारी कक्षा में सबसे ऊपर Q_OBJECT मैक्रो है। साथ ही, हमें आवश्यक मेटा-ऑब्जेक्ट कोड बनाने के लिए प्रोजेक्ट फ़ाइल पर qmake चलाने की आवश्यकता है।

हमारा प्लगइन वर्ग, DialogPlugin , DialogPlugin का एक उपवर्ग है। हमें विरासत में दिए गए फ़ंक्शन, registerTypes() को लागू करने की आवश्यकता है।

DialogPlugin.cpp :

#include "dialogPlugin.h"
#include "directory.h"
#include "file.h"
#include <QtQml>

void DialogPlugin::registerTypes(const char *uri)
{
    // Register the class Directory into QML as a "Directory" type version 1.0
    // @uri FileDialog
    qmlRegisterType<Directory>(uri, 1, 0, "Directory");
    qmlRegisterType<File>(uri, 1, 0, "File");
}

RegisterTypes registerTypes() फ़ंक्शन हमारी फ़ाइल और निर्देशिका कक्षाओं को QML में पंजीकृत करता है। इस फ़ंक्शन को अपने टेम्पलेट के लिए वर्ग नाम, एक प्रमुख संस्करण संख्या, एक लघु संस्करण संख्या और हमारी कक्षाओं के लिए एक नाम की आवश्यकता है। A // @uri <module identifier> टिप्पणी Qt क्रिएटर को इस मॉड्यूल को आयात करने वाली QML फ़ाइलों को संपादित करते समय पंजीकृत प्रकारों से अवगत होने की अनुमति देता है।

C ++ क्लास में QML गुण बनाना

हम C ++ और Qt के मेटा-ऑब्जेक्ट सिस्टम का उपयोग करके QML प्रकार और गुण बना सकते हैं। हम स्लॉट्स और सिग्नल का उपयोग करके गुणों को लागू कर सकते हैं, जिससे क्यूटी को इन गुणों के बारे में पता चलता है। इन गुणों का उपयोग QML में किया जा सकता है।

पाठ संपादक के लिए, हमें फ़ाइलों को लोड करने और सहेजने में सक्षम होना चाहिए। आमतौर पर, ये सुविधाएँ एक फ़ाइल संवाद में निहित होती हैं। सौभाग्य से, हम निर्देशिका पढ़ने और इनपुट / आउटपुट धाराओं को लागू करने के लिए QDir , QFile , और QTextStream का उपयोग कर सकते हैं।

class Directory : public QObject {
    Q_OBJECT

    Q_PROPERTY (int filesCount READ filesCount CONSTANT)
    Q_PROPERTY (QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
    Q_PROPERTY (QString fileContent READ fileContent WRITE setFileContent NOTIFY fileContentChanged)
    Q_PROPERTY (QQmlListProperty<File> files READ files CONSTANT)
    ...

Directory क्लास, Qt के मेटा-ऑब्जेक्ट सिस्टम का उपयोग उन संपत्तियों को पंजीकृत करने के लिए करता है जिन्हें फ़ाइल हैंडलिंग को पूरा करने की आवश्यकता होती है। Directory वर्ग को एक प्लगइन के रूप में निर्यात किया जाता है और क्यूएमएल में Directory प्रकार के रूप में उपयोग करने योग्य है। Q_PROPERTY () मैक्रो का उपयोग करते हुए सूचीबद्ध गुणों में से प्रत्येक एक QML संपत्ति है।

Q_PROPERTY प्रॉपर्टी के साथ-साथ अपने रीड एंड राइट को Qt के मेटा-ऑब्जेक्ट सिस्टम में घोषित करता है। उदाहरण के लिए, टाइप QString का filename गुण, filename() फ़ंक्शन और setFilename() फ़ंक्शन का उपयोग करके पठनीय है। इसके अतिरिक्त, फ़ाइल नाम संपत्ति से संबंधित एक संकेत है जिसे filenameChanged() कहा जाता है, जिसे जब भी संपत्ति परिवर्तित होती है, उत्सर्जित किया जाता है। हेडर फ़ाइल में पढ़ने और लिखने के कार्यों को public घोषित किया गया है।

इसी प्रकार, हमारे पास उनके उपयोग के अनुसार घोषित अन्य गुण हैं। filesCount गुण किसी निर्देशिका में फ़ाइलों की संख्या को इंगित करता है। फ़ाइल नाम गुण वर्तमान में चयनित फ़ाइल के नाम पर सेट है और लोड की गई / सहेजी गई फ़ाइल सामग्री को फ़ाइल संपत्ति में संग्रहीत किया fileContent है।

Q_PROPERTY(QQmlListProperty<File> files READ files CONSTANT)

files सूची गुण निर्देशिका में सभी फ़िल्टर्ड फ़ाइलों की एक सूची है। Directory पाठ को अमान्य पाठ फ़ाइलों को फ़िल्टर करने के लिए लागू किया गया है; केवल .txt एक्सटेंशन वाली फाइलें ही मान्य होती हैं। इसके अलावा, QList s को QML फ़ाइलों में C ++ में QQmlListProperty घोषित करके उपयोग किया जा सकता है। टेम्प्लेटेड ऑब्जेक्ट को QObject से इनहेरिट करने की आवश्यकता QObject , इसलिए, File क्लास को भी QObject से इनहेरिट करना होगा। Directory वर्ग में, File ऑब्जेक्ट्स की सूची एक QList में संग्रहीत की जाती है जिसे m_fileList कहा जाता है।

class File : public QObject{

    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)

    ...
};

प्रॉपर्टीज का उपयोग क्यूएमएल में Directory ऑब्जेक्ट के गुणों के हिस्से के रूप में किया जा सकता है। ध्यान दें कि हमें अपने C ++ कोड में एक पहचानकर्ता id प्रॉपर्टी नहीं बनानी है।

Directory {
    id: directory

    filesCount
    filename
    fileContent
    files

    files[0].name
}

क्योंकि QML जावास्क्रिप्ट के सिंटैक्स और संरचना का उपयोग करता है, हम फ़ाइलों की सूची के माध्यम से पुनरावृत्ति कर सकते हैं और इसके गुणों को पुनः प्राप्त कर सकते हैं। पहली फ़ाइल के नाम की संपत्ति को पुनः प्राप्त करने के लिए, हम files[0].name कह सकते हैं।

QML से नियमित C ++ फ़ंक्शन भी सुलभ हैं। फ़ाइल लोडिंग और सेविंग फंक्शंस C ++ में कार्यान्वित किए जाते हैं और Q_INVOKABLE मैक्रो का उपयोग करके घोषित किए Q_INVOKABLE । वैकल्पिक रूप से, हम फ़ंक्शन को slot रूप में घोषित कर सकते हैं और फ़ंक्शन QML से सुलभ होंगे।

Directory.h directory.h :

Q_INVOKABLE void saveFile();
Q_INVOKABLE void loadFile();

जब भी निर्देशिका सामग्री बदलती है, तो Directory वर्ग को अन्य वस्तुओं को भी सूचित करना होता है। यह सुविधा एक signal का उपयोग करके की जाती signal । जैसा कि पहले उल्लेख किया गया है, क्यूएमएल संकेतों में एक समान हैंडलर होता है, जिसके साथ उनके नाम पूर्व निर्धारित होते हैं। सिग्नल को directoryChanged कहा जाता है और जब भी डायरेक्टरी रिफ्रेश होती है तो इसे उत्सर्जित किया जाता है। रिफ्रेश बस डायरेक्टरी कंटेंट को फिर से लोड करता है और डायरेक्टरी में मान्य फाइलों की सूची को अपडेट करता है। QML आइटम्स को onDirectoryChanged सिग्नल हैंडलर पर कार्रवाई संलग्न करके सूचित किया जा सकता है।

list गुणों को और अधिक तलाशने की आवश्यकता है। ऐसा इसलिए है क्योंकि सूची के गुणों का उपयोग सूची सामग्री को एक्सेस और संशोधित करने के लिए कॉलबैक करता है। सूची गुण QQmlListProperty<File> प्रकार का है। जब भी सूची एक्सेस की जाती है, तो QQmlListProperty<File> फ़ंक्शन को QQmlListProperty<File> वापस करना QQmlListProperty<File> । टेम्पलेट प्रकार, File , एक QObject व्युत्पन्न होना चाहिए। इसके अलावा, QQmlListProperty बनाने के लिए, सूची के QQmlListProperty और संशोधक को फ़ंक्शन पॉइंटर के रूप में कंस्ट्रक्टर को पास करने की आवश्यकता होती है। सूची, हमारे मामले में एक QList , को भी File पॉइंटर्स की सूची होना चाहिए।

QQmlListProperty का निर्माण निम्नानुसार घोषित किया गया है:

QQmlListProperty (QObject *object, void *data, AppendFunction append,
                  CountFunction count = 0, AtFunction at = 0, ClearFunction clear = 0);

यह उन फ़ंक्शन के लिए पॉइंटर्स लेता है जो सूची को जोड़ेंगे, सूची की गणना करेंगे, एक इंडेक्स का उपयोग करके आइटम को पुनः प्राप्त करेंगे, और सूची को खाली करेंगे। केवल append फंक्शन अनिवार्य है। ध्यान दें कि फ़ंक्शन पॉइंटर्स को AppendFunction , CountFunction , AtFunction या ClearFunction की परिभाषा से मेल खाना चाहिए।

Directory वर्ग इस तरह से एक QQmlListProperty उदाहरण का निर्माण करता है:

QQmlListProperty<File>(this, &m_fileList, &appendFiles, &filesSize, &fileAt, &clearFilesPtr);

जहां पैरामीटर निम्नलिखित कार्यों के लिए संकेत हैं:

void appendFiles(QQmlListProperty<File> *property, File *file);
File* fileAt(QQmlListProperty<File> *property, int index);
int filesSize(QQmlListProperty<File> *property);
void clearFilesPtr(QQmlListProperty<File> *property);

हमारी फ़ाइल संवाद को सरल बनाने के लिए, Directory वर्ग अमान्य पाठ फ़ाइलों को फ़िल्टर करता है, जो कि एक .txt एक्सटेंशन नहीं है। यदि किसी फ़ाइल नाम में .txt एक्सटेंशन नहीं है, तो वह हमारी फ़ाइल संवाद में दिखाई नहीं देगी। साथ ही, कार्यान्वयन सुनिश्चित करता है कि सहेजी गई फ़ाइलों का फ़ाइल नाम में .txt एक्सटेंशन है। Directory फ़ाइल को पढ़ने के लिए और फ़ाइल में फ़ाइल सामग्री को आउटपुट करने के लिए QTextStream का उपयोग करता है।

हमारी Directory ऑब्जेक्ट के साथ, हम फ़ाइलों को एक सूची के रूप में पुनः प्राप्त कर सकते हैं, यह जान सकते हैं कि एप्लिकेशन निर्देशिका में कितनी पाठ फाइलें हैं, फ़ाइल का नाम और सामग्री को स्ट्रिंग के रूप में प्राप्त करें, और जब भी निर्देशिका सामग्री में परिवर्तन हो, तो सूचित करें।

प्लगइन का निर्माण करने के लिए, qmake फाइल पर qmake को रन करें, फिर plugins निर्देशिका में प्लगइन को बनाने और स्थानांतरित करने के लिए रन make

QML में एक प्लगइन आयात करना

qmlscene उपकरण फ़ाइलों को आवेदन के रूप में उसी निर्देशिका में हैं आयात करता है। हम एक qmldir फ़ाइल भी बना सकते हैं जिसमें वे सामग्री हैं जो हम आयात करना चाहते हैं। इस मामले में, केवल प्लगइन है, लेकिन अन्य संसाधनों (क्यूएमएल प्रकार, जावास्क्रिप्ट फाइलें) को एक qmldir अच्छी तरह से परिभाषित किया जा सकता है ।

qmldir फ़ाइल की सामग्री :

module FileDialog
plugin filedialogplugin

हमारे द्वारा अभी बनाया गया मॉड्यूल कहा जाता है FileDialog , और यह एक प्लगइन उपलब्ध कराता है जिसे कहा जाता filedialogplugin है TARGET जो प्रोजेक्ट फ़ाइल में फ़ील्ड से मेल खाता है । क्योंकि हमने प्लगइन के लिए एक पथ निर्दिष्ट नहीं किया था, क्यूएमएल इंजन को उसी निर्देशिका में qmldir फ़ाइल के रूप में खोजने की उम्मीद है ।

QML प्रकार जो हमारे प्लगइन द्वारा पंजीकृत हैं, अब QML में आयात किए जा सकते हैं:

import FileDialog 1.0

Directory {
    id: directory
}
...

फ़ाइल मेनू में एक फ़ाइल संवाद को एकीकृत करना

हमारी FileMenu ज़रूरत FileDialog ऑब्जेक्ट को प्रदर्शित करने की है, जिसमें एक निर्देशिका में पाठ फ़ाइलों की एक सूची है, जिससे उपयोगकर्ता को सूची पर क्लिक करके फ़ाइल का चयन करने की अनुमति मिलती है। हमें अपने कार्यों के लिए सेव, लोड और नए बटन भी असाइन करने होंगे। FileMenu में कीबोर्ड का उपयोग करके उपयोगकर्ता को फ़ाइल नाम टाइप करने की अनुमति देने के लिए एक संपादन योग्य पाठ इनपुट होता है।

Directory वस्तु में प्रयोग किया जाता है FileMenu.qml फ़ाइल और यह सूचित करता है FileDialog उद्देश्य यह है कि निर्देशिका इसकी सामग्री रिफ्रेश किया गया। यह सूचना सिग्नल हैंडलर में दी जाती है onDirectoryChanged

इन FileMenu.qml :

Directory {
    id: directory
    filename: textInput.text
    onDirectoryChanged: fileDialog.notifyRefresh()
}

हमारे आवेदन की सादगी को ध्यान में रखते हुए, फ़ाइल संवाद हमेशा दिखाई देगा और अमान्य पाठ फ़ाइलों को प्रदर्शित नहीं करेगा, जिसमें .txt उनके फ़ाइलनाम का विस्तार नहीं है ।

इन FileDialog.qml :

signal notifyRefresh()
onNotifyRefresh: dirView.model = directory.files

FileDialog वस्तु अपनी सूची संपत्ति बुलाया पढ़ कर एक निर्देशिका की सामग्री को प्रदर्शित करेगा files । फ़ाइलों को एक ग्रिड GridView ऑब्जेक्ट के मॉडल के रूप में उपयोग किया जाता है , जो एक प्रतिनिधि के अनुसार ग्रिड में डेटा आइटम प्रदर्शित करता है। प्रतिनिधि मॉडल की उपस्थिति को संभालता है और हमारी फ़ाइल संवाद बस बीच में केंद्रित पाठ के साथ एक ग्रिड बनाएगा। फ़ाइल नाम पर क्लिक करने से फ़ाइल नाम हाइलाइट करने के लिए एक आयत की उपस्थिति होगी। FileDialog जब भी सूचित किया जाता है notifyRefresh संकेत उत्सर्जित होता है, निर्देशिका में फ़ाइलों को पुन: लोड।

इन FileMenu.qml :

Button {
    id: newButton
    label: "New"
    onButtonClick: {
        textArea.textContent = ""
    }
}
Button {
    id: loadButton
    label: "Load"
    onButtonClick: {
        directory.filename = textInput.text
        directory.loadFile()
        textArea.textContent = directory.fileContent
    }
}
Button {
    id: saveButton
    label: "Save"
    onButtonClick: {
        directory.fileContent = textArea.textContent
        directory.filename = textInput.text
        directory.saveFile()
    }
}
Button {
    id: exitButton
    label: "Exit"
    onButtonClick: {
        Qt.quit()
    }
}

हम FileMenu अब उनके संबंधित कार्यों से जुड़ सकते हैं। saveButton से पाठ स्थानांतरित करेंगे TextEdit निर्देशिका के पर fileContent संपत्ति है, तो संपादन योग्य पाठ इनपुट से अपनी फ़ाइल नाम कॉपी। अंत में, बटन saveFile() फ़ंक्शन को कॉल करता है, फ़ाइल को सहेजता है। loadButton एक ऐसी ही निष्पादन है। इसके अलावा, New कार्रवाई की सामग्री को खाली कर देगा TextEdit

इसके अलावा, EditMenu बटन TextEdit टेक्स्ट एडिटर में सभी टेक्स्ट को कॉपी, पेस्ट और सेलेक्ट करने के लिए फंक्शन्स से जुड़े होते हैं ।

अंतिम पाठ संपादक अनुप्रयोग

आवेदन एक साधारण पाठ संपादक के रूप में कार्य कर सकता है, पाठ को स्वीकार करने और इसे एक फ़ाइल में सहेजने में सक्षम है। यह एक फ़ाइल को लोड कर सकता है और पाठ हेरफेर कर सकता है।

पाठ संपादक चलाना

पाठ संपादक चलने से पहले हमें फ़ाइल संवाद C ++ प्लगइन बनाने की आवश्यकता है। इसे बनाने के लिए, प्रवेश filedialog निर्देशिका, तो चलाने qmake और का उपयोग कर संकलन make या nmake , आपके प्लेटफ़ॉर्म पर निर्भर।

qmlscene साथ टेक्स्ट एडिटर को qmlscene , आयात निर्देशिका को एक पैरामीटर के रूप में पास करें ताकि QML इंजन को पता चल जाए कि हमारे फ़ाइल संवाद प्लगइन को आयात करने वाले मॉड्यूल की तलाश कहां है:

qmlscene -I ./imports texteditor.qml

पूर्ण स्रोत कोड examples/quick/tutorials/gettingStartedQml निर्देशिका में है।

Original text