2016-08-31 19 views
7

कल्पना करें कि टाइल्स से भरे विशाल आयताकार ग्रिड की कल्पना करें। व्यक्तिगत टाइल्स बहुत जटिल नहीं हैं, वे एसवीजी छवियां हैं जिनमें कम मात्रा में आकार होते हैं।QML में टाइल्स के विशाल परिवेश को कैसे संभालें?

विभिन्न प्रकार के टाइल्स की संख्या बहुत बड़ी नहीं है, मैं कम सैकड़ों में अनुमान लगाता हूं। हालांकि, ग्रिड बहुत बड़ा हो सकता है, इसलिए कुल टाइल्स की संख्या बहुत बड़ी है (कम से कम हजारों, शायद अधिक)।

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

यह भी अच्छा होगा अगर मैं इसे असीमित रूप से पॉप्युलेट कर सकता हूं, पहले तत्व जो वास्तव में दिखाई दे रहे हैं, और बाकी बाकी हैं। इसका मतलब यह है कि एक टेबल-हैंडलिंग क्लास जहां मुझे पहली बार लूप में पंक्तियां और कॉलम जोड़ना होता है, वह सबसे अच्छा समाधान नहीं होगा, क्योंकि शुरुआती स्थिति ऊपरी बाएं कोने की आवश्यकता नहीं है।

ज़ूमिंग केवल स्केलिंग कारक के एकाधिक के रूप में निर्दिष्ट टाइल के भीतर सभी width और height आइटमों के गुणों से प्राप्त किया जाता है। svg कोई समस्या नहीं होनी चाहिए क्योंकि विभिन्न छवियों की संख्या अधिक नहीं है, इसे कैश किया जा सकता है। असंभव मामले में svg बाधा बन गई, मैं अलग-अलग प्रस्तावों में अलग-अलग png एस के सेट का उपयोग कर सकता था।

मैंने कोशिश की है (या माना जाता है) निम्नलिखित दृष्टिकोण:

  1. SameGame example के तरीकों का उपयोग करना, QML बनाने गतिशील वस्तुओं (Component.createObject)। यह काम करता है अगर वस्तुओं की संख्या छोटी है, लेकिन बड़ी संख्या में वस्तुओं के साथ बहुत धीमी है। यहां तक ​​कि यदि ऑब्जेक्ट्स पूरी तरह खाली हैं, तो यह विधि very long time लेती है।

  2. का उपयोग Flickable के अंदर Repeater का उपयोग करना। Flickable में Grid है, जो Repater द्वारा पॉप्युलेट किया गया है। Grid, ज़ाहिर है, बहुत अधिक है। यह विधि गतिशील रूप से वस्तुओं को बनाने से तेज़ है, लेकिन अभी भी अक्षम है क्योंकि टाइल्स की संख्या बढ़ती है। क्यूएमएल इंजन प्रत्येक आइटम का ट्रैक रखता है, यहां तक ​​कि जो दिखाई नहीं दे रहे हैं। ज़ूमिंग भी काफी धीमी है, क्योंकि प्रत्येक आइटम के गुणों का पुनर्मूल्यांकन किया जाता है, केवल दृश्यमान नहीं।

  3. GridView का उपयोग करना। यह पहली नज़र में सही समाधान की तरह दिखता है। GridView विरासत Flickable है, और यह केवल सामग्री को प्रस्तुत करने की देखभाल करता है जो दृश्य की सीमाओं के भीतर हैं। यहां तक ​​कि लाखों एसवीजी छवियों के साथ एक टेस्ट केस भी तेजी से चलता है, और यह आसानी से स्क्रॉल और आकार बदलता है। केवल एक समस्या है: GridView या तो क्षैतिज या लंबवत है, लेकिन दोनों नहीं। 2012 के बाद से इस बारे में feature request रहा है, लेकिन यह अभी भी अनदेखा प्रतीत होता है।

  4. सीधे QGraphicsView का उपयोग करना। यह is capable आवश्यक तत्वों को प्रदर्शित करने, स्क्रॉल करने और ज़ूम करने के लिए, लेकिन यह QML- आधारित नहीं है। मेरा बाकी जीयूआई क्यूएमएल में है, और मैंने केवल QML और QGraphicsView के संयोजन के बारे में डरावनी कहानियां पढ़ी हैं। मैंने कभी इसका कोई उचित उदाहरण नहीं देखा है।

अन्य समाधान क्या हैं?एक में घूमते समय एक साधारण GridLayout (जो केवल कुछ पंक्तियों और दृश्यमान क्षेत्र से बड़े कॉलम हैं) के पंक्तियों और स्तंभों को जोड़ने और निकालने के लिए जावास्क्रिप्ट का उपयोग करने के कुछ भयानक हैक? या बस एक ओपनजीएल विंडो एम्बेड कर रहा है और सब कुछ मैन्युअल रूप से ड्राइंग कर रहा है?

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

+1

डॉस और विंडोज 95 के खिलाफ तुलना कोई समझ नहीं लेती है, क्योंकि अंतर्निहित प्रौद्योगिकियां और दृष्टिकोण बेहद अलग हैं। एक कस्टम QtQuick तत्व का उपयोग क्यों नहीं करते जो आपको चाहिए? – peppe

+0

@peppe: मेरा बिंदु सिस्टम ही नहीं था, लेकिन 200 बार कम कम्प्यूटेशनल पावर के साथ ऐसा करना संभव था। और "कस्टम QtQuick तत्व" से आपका मतलब है कि मुझे अपने 2 डी ग्राफिक्स इंजन को खरोंच से लागू करना चाहिए? हां, यह संभव होगा, लेकिन यह दृष्टिकोण ओपनजीएल ड्राइंग समाधान के समान है। 'ग्रिड व्यू' को यह जानने का लाभ था कि क्या और कब लोड करना और अनलोड करना है। खरोंच से सबकुछ करके, मुझे अपना खुद का मेमोरी प्रबंधन, दृश्यता गणना, सबकुछ लागू करना होगा। तो अगर मुझे स्क्रैच से सब कुछ लागू करना है तो क्यूटी का उपयोग क्यों करें? – vsz

+1

आप आज भी पूरी तरह से कर सकते हैं, लेकिन 10000 तत्वों के साथ एक पुनरावर्तक सिर्फ गलत दृष्टिकोण है। तथ्य यह है कि क्यूएमएल में ऐसी अंतर्निहित चीज की कमी है इसका मतलब यह नहीं है कि हासिल करना असंभव है। – peppe

उत्तर

1

हाँ, क्यूटी वर्षों के लिए सामुदायिक सुझावों को अनदेखा करने में बहुत अच्छा है, भले ही वे बेहद उपयोगी हों, महत्वपूर्ण मानते हैं, और zip support जैसे सबसे अधिक वोट देने वाले होते हैं।

मैं व्यक्तिगत रूप से GridView "फिक्सिंग" परेशान नहीं करता, बल्कि सी ++ में अपनी विशिष्ट आवश्यकताओं के अनुरूप स्क्रैच से कुछ लागू करता हूं ताकि यह तेज़ और कुशल हो। और यदि आपकी टाईल्स एक समान वर्ग हैं तो यह बहुत आसान होगा, और ऐसा लगता है जैसे आप इससे दूर हो सकते हैं, भले ही अंदर वास्तविक छवियां स्क्वायर न हों। यह प्रोग्रामेटिक रूप से अपने पदों को निर्धारित करना बहुत आसान बना देगा, और शीर्ष बाएं कोने टाइल भी निर्धारित करेगा, प्रति लाइन कितनी टाइलें और बाद की रेखाओं के लिए आगे बढ़ेंगी। फिर दृश्यता आयत के चलते आप दृश्यता दर्ज करने वाले लोगों के लिए QML तत्व बनाने के लिए अपने कंटेनर को सिग्नल करते हैं और सिग्नल करते हैं। बहुत आसान।

आपको किसी भी फैंसी की आवश्यकता नहीं है, केवल QObject का वारिस करें, टाइप को QML पर पंजीकृत करें, फिर जाएं और इसके आंतरिक "मॉडल" को पॉप्युलेट करें। आप निश्चित रूप से स्मृति में सभी ऑब्जेक्ट्स नहीं रखना चाहते हैं, भले ही दृश्य ग्राफ उन्हें प्रस्तुत करने के लिए पर्याप्त स्मार्ट न हो, फिर भी यह उन्हें संसाधित करेगा, मुझे संदेह है कि एफपीएस में आपकी बूंद एक जीपीयू का उत्पाद नहीं है बल्कि एक सीपीयू बाधा है ।

वास्तविक ग्रिड ऑब्जेक्ट उनके डेटा Q_SIGNAL void create(x, y, imgPath); के साथ सृजन और विनाश संकेतों को उत्सर्जित कर सकता है, इसलिए आप क्यूएमएल पक्ष पर कस्टम हैंडलर बांधते हैं, जो आपको लचीलापन और उपयोग में आसानी प्रदान करेगा, जैसे आसानी से "प्रतिनिधि" ऑब्जेक्ट को निर्दिष्ट करना, यह सी ++ में वास्तविक निर्माण/विनाश करने से अधिक सुरुचिपूर्ण होगा। आप कुछ आइटमों के लिए क्यूएमएल पक्ष पर बाइंडिंग का उपयोग कर सकते हैं, जो ट्रैक से बाहर निकलने के लिए दृश्यमान होते हैं, जिससे जटिलता कम हो जाती है, क्योंकि आपको सभी "जीवित" वस्तुओं को ट्रैक नहीं करना पड़ेगा।

Component { 
    id: objComponent 
    Image { 
     property bool isVisible: { is in grid.visibleRect ??? } 
     onIsVisibleChanged: if (!isVisible) destroy() 
    } 
} 

MyGrid { 
    id: grid 
    contentX: flickable.contentX 
    contentY: flickable.contentY 

    onCreate: objComponent.createObject(flickable.contentItem, {"x" : x, "y" : y, "source" : imgPath}) 
} 

Flickable { 
    id: flickable 
    contentWidth: grid.contentWidth 
    contentHeight: grid.contentHeight 
} 

आम तौर पर, एक उपयोगकर्ता एक सवाल है, एक इनाम मैं कोड काम का उत्पादन होता है की पेशकश करने के लिए पर्याप्त महत्वपूर्ण है, लेकिन दुर्भाग्य से मैं इस समय बहुत व्यस्त हूँ जब। अवधारणा बहुत सरल है हालांकि इसे लागू करने के लिए बहुत ही समस्याग्रस्त नहीं होना चाहिए।

+2

ग्रिड व्यू * * सी ++ में लागू किया गया है। –

+0

@ डेविडके.हेस - भी, जिन्होंने दावा किया कि यह नहीं है? – dtech