//Is this possible in any way?
//Q_PROPERTY(AnimalModel modelAnimals READ modelAnimals NOTIFY modelAnimalsChanged)
हाँ, यह है, तो आप की कोशिश नहीं की? बेशक, यह AnimalModel
नहीं होगा लेकिन AnimalModel *
होगा, लेकिन जब तक मॉडल QAbstractListModel
प्राप्त करता है, तो आपको बस इतना ही चाहिए। आपको NOTIFY
भाग की भी आवश्यकता नहीं है, परिवर्तन के रूप में, मॉडल के लिए आंतरिक स्वचालित रूप से वैसे भी दिखाई देगा। modelAnimalsChanged
केवल तभी समझ में आता है जब आप पूरे मॉडल को एक अलग मॉडल के साथ प्रतिस्थापित करते हैं, और स्वाभाविक रूप से, बिना किसी संकेत के एक संपत्ति का उपयोग करने के बारे में QML की चेतावनियों को बंद करने के लिए। जब मॉडल ऑब्जेक्ट नहीं बदलता है तो बाद वाले को करने का एक क्लीनर तरीका है स्लॉट या Q_INVOKABLE
से AnimalModel *
लौटाएं।
यदि आप वास्तव में लचीला मॉडल चाहते हैं, तो आप QObject *
स्टोर कर सकते हैं, फिर QML से आप मनमानी गुणों के साथ मनमानी वस्तुओं को बना सकते हैं, और मॉडल में जोड़ सकते हैं। फिर मॉडल से आपके पास एक object
भूमिका है जो ऑब्जेक्ट लौटाती है, और आप ऑब्जेक्ट्स को क्वेरी और पुनर्प्राप्त करने के लिए ऑब्जेक्ट का उपयोग कर सकते हैं। जबकि एक "शास्त्रीय" सूची मॉडल कार्यान्वयन एक स्थिर, निश्चित स्कीमा वाले मॉडल को परिभाषित करेगा, इस दृष्टिकोण का उपयोग करके मॉडल में अलग-अलग गुणों के साथ "असंगत" ऑब्जेक्ट्स की अनुमति मिलती है।
स्वाभाविक रूप से, इसके लिए कुछ प्रकार की सुरक्षा की आवश्यकता होती है, उदाहरण के लिए इस मॉडल में प्रत्येक ऑब्जेक्ट के लिए property int type
है, और इसके आधार पर आप ऑब्जेक्ट के लिए उपलब्ध गुण निर्धारित कर सकते हैं। मेरा सामान्य दृष्टिकोण एक प्रतिनिधि के लिए Loader
होना है, और यह ऑब्जेक्ट को तत्काल करने वाले ऑब्जेक्ट प्रकार को विज़ुअलाइज़ करने वाले विभिन्न QML UI कार्यान्वयन के लिए डेटा स्रोत के रूप में ऑब्जेक्ट पास करता है। इस तरह आपके पास मॉडल में अलग-अलग ऑब्जेक्ट्स और अलग-अलग QML आइटम प्रतिनिधि प्रतिनिधियों के रूप में हैं।
परम "सभी ट्रेडों के जैक" बनाने के लिए अंतिम चरण सूची/मॉडल वस्तु इसके लिए QQmlListProperty
और Q_CLASSINFO("DefaultProperty", "container")
लागू करने के लिए, आप दोनों सूची/मॉडल गतिशील रचना के लिए अनुमति देता है, या QML के कथात्मक वाक्यविन्यास का उपयोग है। यह भी ध्यान रखें कि इस समाधान के साथ, आप ऐसे मॉडल से जोड़ या निकाल सकते हैं, यहां तक कि घोषणात्मक रूप से तत्काल वस्तुओं को भी हटा सकते हैं।
इसके अलावा, आपके उपयोग परिदृश्य के आधार पर, आपको मॉडल के लिए qmlRegisterType()
या qmlRegisterUncreatableType()
होना पड़ सकता है।
ठीक है, दूसरी नज़र में, यह "किसी भी डेटा के मॉडल" जैसा दिखता है, जिसका मतलब स्कीमा-कम मॉडल नहीं था बल्कि बस अलग-अलग स्कीमा मॉडल थे। उस स्थिति में, AnimalModel *
लौटने की बजाय, आप QAbstractListModel *
या यहां तक कि QObject *
का उपयोग कर सकते हैं - यह क्यूएमएल में भी काम करेगा, क्योंकि यह मेटा सिस्टम के माध्यम से गतिशीलता को नियोजित करता है। लेकिन किसी भी दर पर, स्कीमा-कम मॉडल अधिक शक्तिशाली और लचीले होते हैं, और उन्हें परिभाषित करने के लिए सी ++ कोड की आवश्यकता नहीं होती है, यह सब अकेले क्यूएमएल से काम कर सकते हैं।
class List : public QAbstractListModel {
Q_OBJECT
QList<QObject *> _data;
Q_PROPERTY(int size READ size NOTIFY sizeChanged)
Q_PROPERTY(QQmlListProperty<QObject> content READ content)
Q_PROPERTY(QObject * parent READ parent WRITE setParent)
Q_CLASSINFO("DefaultProperty", "content")
public:
List(QObject *parent = 0) : QAbstractListModel(parent) { }
int rowCount(const QModelIndex &p) const { Q_UNUSED(p) return _data.size(); }
QVariant data(const QModelIndex &index, int role) const {
Q_UNUSED(role)
return QVariant::fromValue(_data[index.row()]);
}
QHash<int, QByteArray> roleNames() const {
static QHash<int, QByteArray> * pHash;
if (!pHash) {
pHash = new QHash<int, QByteArray>;
(*pHash)[Qt::UserRole + 1] = "object";
}
return *pHash;
}
int size() const { return _data.size(); }
QQmlListProperty<QObject> content() { return QQmlListProperty<QObject>(this, _data); }
public slots:
void add(QObject * o) {
int i = _data.size();
beginInsertRows(QModelIndex(), i, i);
_data.append(o);
o->setParent(this);
sizeChanged();
endInsertRows();
}
void insert(QObject * o, int i) {
beginInsertRows(QModelIndex(), i, i);
_data.insert(i, o);
o->setParent(this);
sizeChanged();
endInsertRows();
}
QObject * take(int i) {
if ((i > -1) && (i < _data.size())) {
beginRemoveRows(QModelIndex(), i, i);
QObject * o = _data.takeAt(i);
o->setParent(0);
sizeChanged();
endRemoveRows();
return o;
} else qDebug() << "ERROR: take() failed - object out of bounds!";
return 0;
}
QObject * get(int i) {
if ((i > -1) && (i < _data.size())) return _data[i];
else qDebug() << "ERROR: get() failed - object out of bounds!";
return 0;
}
signals:
void sizeChanged();
};
उसके बाद, आप qmlRegisterType<List>("Core", 1, 0, "List");
के बाद आप इसे काफी किसी भी तरह से आप चाहते हैं का उपयोग कर सकते हैं - यह स्वाभाविक रूप से QMLs QtObject
यह सीधे एक ListView
ड्राइव करने के लिए एक मॉडल के रूप में इस्तेमाल किया जा सकता है सहित किसी भी QObject
पकड़ या व्युत्पन्न जाएगा। आप यह गतिशील, स्लॉट या कथात्मक का उपयोग कर इस तरह पॉप्युलेट कर सकते हैं:
List {
QtObject { ... }
QtObject { ... }
List {
QtObject { ... }
QtObject { ... }
}
}
यह भी वस्तु स्वामित्व संभाल लेंगे, और आप आसानी घोंसला यह, सार में एक बंटे पेड़ मॉडल का निर्माण कर सकते हैं - ध्यान दें कि आप एलान के तौर पर नहीं कर सकते क्यूएमएल के ListModel
के साथ ऐसा करें। आप parentChanged
सिग्नल जोड़ना चाहते हैं और एक सेटटर को कार्यान्वित करना चाहते हैं जो इसे बदलता है यदि आप एक बदलते माता-पिता के खिलाफ बाध्य करना चाहते हैं, तो मेरे मामले में यह आवश्यक नहीं था।
कैसे एक दृश्य के साथ इसका इस्तेमाल करने के रूप में, आप objectName
संपत्ति या एक int type
संपत्ति उपयोग कर सकते हैं, और प्रतिनिधि के लिए एक Loader
का उपयोग करें:
Loader {
width: childrenRect.width
height: childrenRect.height
}
आप ऑब्जेक्ट नाम का उपयोग करते हैं, तो आप कर लोडर name.qml
फ़ाइल बनाते हैं, यदि आप int का उपयोग करते हैं, तो आप Component
एस की सरणी बना सकते हैं और उपयुक्त घटक का उपयोग स्रोत घटक के रूप में कर सकते हैं। आप Loader
की एक संपत्ति के रूप में object
बेनकाब कर सकते हैं या तो और वास्तविक वस्तु यूआई यह parent.object.prop
संदर्भ है, या आप setSource(name + ".qml", {"object": object})
का उपयोग करें और वस्तु संपत्ति है कि आइटम में सीधे हो सकता है, फिर भी setSource
केवल, बाहरी स्रोतों के साथ काम करेंगे इनलाइन Component
साथ नहीं रों। ध्यान दें कि बाहरी स्रोत के मामले में, object
इसे आगे बढ़ाने के लिए कुछ भी किए बिना भी पहुंच योग्य होगा, हालांकि किसी कारण से यह इनलाइन घटकों के साथ काम नहीं करता है, ऐसे घटकों के साथ ही इसे एक संभावित संपत्ति के रूप में उजागर करना संभव है लोडर
बहुत सारे रोचक विचारों के साथ बहुत ही जटिल उत्तर के लिए धन्यवाद। आप सही थे कि रूट समस्या अमान्य 'Q_PROPERTY' प्रकार में थी। 'AnimalModel *' के साथ यह बहुत अच्छा काम करता है। 'QObject * 'के मॉडल के संबंध में, यह मेरे पास पहले से कुछ है (stackoverflow.com/questions/35065627/...)। लेकिन क्या आप उदाहरण पोस्ट कर सकते हैं या 'Q_CLASSINFO' और' qmlRegisterType' उपयोग केस के बारे में अधिक विशिष्ट हो सकते हैं? यह दिलचस्प लगता है लेकिन मुझे यकीन नहीं है कि इस मामले में इसका उपयोग कैसे किया जाए। –
@ लुडेकवोडिका - मैंने कुछ कोड जोड़ा, आपके प्रश्न को फिर से शीर्षक देने की स्वतंत्रता भी ली ताकि कोड उन लोगों के लिए अधिक सुलभ हो जो समान समाधान की तलाश में हैं। – dtech
यह बिल्कुल उत्कृष्ट कृति है। मैं पिछले महीने और आधा क्यूएमएल सीख रहा हूं और मुझे नहीं पता था कि इसे इस तरह के महान तरीके से जोड़ा जा सकता है। स्पष्टीकरण और उदाहरणों के लिए धन्यवाद। एकमात्र सवाल जो मेरे दिमाग में आता है। QHashMap केवल स्थैतिक के बजाय स्थिर पीआरटी के रूप में क्यों? इसे 'स्थिर QHash भूमिकाएं {{{ऑब्जेक्ट रोल, "ऑब्जेक्ट"}} के रूप में परिभाषित करना संभव है; लेकिन इसे सी ++ 11 की आवश्यकता है। क्या यही कारण था? –