2011-12-09 7 views
13

मैं एक पुन: प्रयोज्य QML घटक बनाने का प्रयास कर रहा हूं जो आंतरिक रूप से ग्रिड व्यू होस्ट करता है। ग्रिड व्यू में प्रत्येक तत्व में व्यवहार का एक सेट होता है (ज्यादातर डिस्प्ले और माउस-आधारित सामान) जो पूरे एप्लिकेशन में आम है। हालांकि, ग्रिड व्यू तत्वों के अंदर क्या प्रदर्शित होता है उपयोग-मामले के आधार पर बदलता है। (यानी, एक ग्रिड व्यू के लिए एक ही encapsulated घटक है, लेकिन आवेदन में कहीं और यह एक अलग घटक का उपयोग कर सकते हैं।)क्यूएमएल: मैं ग्रिड व्यू (या लिस्ट व्यू) प्रतिनिधि के अंदर लोड किए गए प्रतिनिधि को मॉडल गुण कैसे पास कर सकता हूं?

तो, मैं क्या करना चाहता हूं प्रत्येक आवेदक आपूर्ति एक प्रतिनिधि है जो प्रत्येक तत्व में जोड़ा जाता है ग्रिड व्यू में, जो पहले से ही एक प्रतिनिधि है। दूसरे शब्दों में, कुछ इस तरह:

MyGrid.qml

import QtQuick 1.1 

Rectangle { 
    id: myGrid 
    objectName: "myGrid" 

    property Component internalDelegate 
    property variant internalModel 

    GridView { 
    anchors.fill: parent 

    delegate: Row { 
     Loader { 
     sourceComponent: myGrid.internalDelegate 
     } 
    } 

    model: parent.internalModel 
    } 
} 

विचार है कि GridView प्रतिनिधि अंदर लोडर को लोड करता है उपयोगकर्ता के आपूर्ति प्रतिनिधि, कुछ इस तरह दिखेगा जो है:

Main.qml

import QtQuick 1.1 

Rectangle { 
    anchors.fill: parent 

    width: 300 
    height: 200 

    MyGrid { 
    anchors.fill: parent 

    internalDelegate: Text { 
     text: name 
    } 

    internalModel: ListModel { 
     ListElement { 
     name: "a" 
     } 

     ListElement { 
     name: "b" 
     } 
    } 
    } 
} 
हालांकि

, इस नहीं है काम। क्यूएमएल रिपोर्ट करता है कि टेक्स्ट नाम के अंदर "नाम" अज्ञात चर है। यदि मैं नाम चर को एक स्ट्रिंग (यानी "हैलो") से प्रतिस्थापित करता हूं, तो यह अपेक्षा के अनुसार काम करता है।

मेरा सवाल यह है कि, मैं "नाम" चर को आंतरिक डिलीगेट में कैसे पास कर सकता हूं, या बेहतर अभी तक, संपूर्ण मॉडल को इतना आंतरिक उपलब्ध कर सकता हूं। डिलीगेट उन सभी तक पहुंच सकता है (क्योंकि कॉलर मॉडल को भी परिभाषित कर रहा है)।

एक साइड सवाल यह है: क्या ऐसा करने का कोई बेहतर तरीका है?

उत्तर

12

मैंने इसे हल किया:

MyGrid।qml

import QtQuick 1.1 

Rectangle { 
    id: myGrid 
    objectName: "myGrid" 

    property Component internalDelegate 
    property variant internalModel 

    GridView { 
     id: grid 
     anchors.fill: parent 

     delegate: Row { 
      Loader { 
       sourceComponent: myGrid.internalDelegate 
       property variant modelData: grid.model.get(index) 
      } 
     } 

     model: parent.internalModel 
    } 
} 

main.qml आयात QtQuick 1,1

Rectangle { 
    anchors.fill: parent 

    width: 300 
    height: 200 

    MyGrid { 
     anchors.fill: parent 

     internalDelegate: Text { 
      text: modelData.name 
     } 

     internalModel: ListModel { 
      ListElement { 
       name: "a" 
      } 

      ListElement { 
       name: "b" 
      } 
     } 
    } 
} 

अगर यह "बेहतर" है पता नहीं है, लेकिन यह कम और सरल कोड है। सूची मॉडल थोड़ा अजीब हैं और क्यूएमएल में वास्तव में संगत नहीं हैं। और ध्यान रखें कि model.get (अनुक्रमणिका) का ग्रिड व्यू का स्वामित्व है क्योंकि पूरे मॉडल का स्वामित्व है। तो यदि सूची नष्ट होने के बाद आप उस वस्तु का उपयोग करना चाहते हैं तो आपको इसे प्रतिलिपि बनाना या प्रतिलिपि बनाना होगा।

+0

मैं घाव मेरी परियोजना के लिए अपनी तकनीक का उपयोग कर। कम कोड बेहतर है और मुझे यह पसंद है कि यह बाध्यकारी घटक की पूरी तरह से आवश्यकता को कैसे हटा देता है। धन्यवाद! –

4

मैं अपने स्वयं के प्रश्न का उत्तर दे रहा हूं क्योंकि मैंने समस्या पर काम करना जारी रखा और एक स्वीकार्य समाधान पाया। मैं इस सवाल को उत्तर के रूप में चिह्नित नहीं कर रहा हूं (अभी तक) क्योंकि मैं जानना चाहता हूं कि क्या आसान या अधिक कुशल समाधान हैं या नहीं।

यहां बताया गया है कि मैंने इस समस्या को कैसे हल किया: मैंने लोडर के साथ बाध्यकारी घटक का उपयोग किया और एक कस्टम MyDelegate घटक बनाया जिसमें मॉडल की वर्तमान सूचीकरण के लिए एक भिन्नता संपत्ति है। टिप्पणियों द्वारा चिह्नित महत्वपूर्ण परिवर्तनों के साथ संशोधित कोड यहां दिया गया है।

Main.qml

import QtQuick 1.1 

Rectangle { 
    anchors.fill: parent 

    width: 300 
    height: 200 

    MyGrid { 
    anchors.fill: parent 

    // *** Use MyDelegate rather than generic Component and refer to 
    // *** model's properties via MyDelegate's model property 
    internalDelegate: MyDelegate { 
     Text { 
     text: model.index + model.name 
     } 
    } 

    internalModel: ListModel { 
     ListElement { 
     name: "a" 
     } 

     ListElement { 
     name: "b" 
     } 
    } 
    } 
} 

MyGrid.qml

import QtQuick 1.1 

Rectangle { 
    id: myGrid 
    objectName: "myGrid" 

    property Component internalDelegate 
    property variant internalModel 

    GridView { 
    anchors.fill: parent 

    delegate: Row { 
     Loader { 
     id: loader 

     sourceComponent: myGrid.internalDelegate 

     // *** Bind current model element to the component 
     // *** when it's loaded 
     Binding { 
      target: loader.item 
      property: "model" 
      value: model 
      when: loader.status == Loader.Ready 
     } 
     } 
    } 

    model: parent.internalModel 
    } 
} 

महत्वपूर्ण इसके अलावा एक कस्टम MyDelegate घटक है, जो एक प्रकार के रूप में मॉडल संपत्ति परिभाषित करता है। यह व्याख्या-समय पर बांधता है, जिसका अर्थ है कि मॉडल की नाम संपत्ति का संदर्भ देने पर Main.qml में कोई त्रुटि नहीं है।

MyDelegate.qml

import QtQuick 1.1 

Rectangle { 
    property variant model 
} 

कुछ वहाँ यह करने के लिए एक और भी आसान तरीका है, लेकिन यह अभी के लिए काम करता है मुझसे कहता है।

12

बस यहाँ का कहना है कि "grid.model.get (model.index)" हैं:

delegate: Row { 
     Loader { 
      sourceComponent: myGrid.internalDelegate 
      property QtObject modelData: grid.model.get(index) //< 
     } 
    } 

"मॉडल" के बराबर है वर्तमान संदर्भ के तहत:

delegate: Row { 
     Loader { 
      sourceComponent: myGrid.internalDelegate 
      property QtObject modelData: model //< 
     } 
    } 
+1

धन्यवाद, तो मुझे पता है कि "QtObject" एक qml डेटाटाइप हो सकता है। – Brent81

संबंधित मुद्दे