كابستراكتليستموديل و كيليست محول
-
29-10-2019 - |
سؤال
يخزن تطبيقي بعض الكائنات من النوع الذي يرث من
QAbstractListModel
الأشياء.
هذا يولد الكثير من التعليمات البرمجية المكررة عند التفاف بسيطة
std::vector<T>
أو أ QList<T>
في النموذج مع الإضافة العامة,
حذف وظيفة الاختيار المتعدد.
هل هذا هو الطريق QAbstractListModel
من المفترض أن تستخدم أو هناك
بعض فئة المحول التي يمكن إزالة التعليمات البرمجية المكررة (على الأقل ل
الحاويات التي هي جزء من كيو تي)?
مثال:أريد أن التفاف vector<ObjectA>
و vector<ObjectB>
في نموذج.رمز ل insertRows
, deleteRows
, columnCount
الخ.دائما ما تكون هي نفسها ، وأود أن تعزيز ذلك (مع القليل من البرمجة الفوقية التي يمكن أن تعمل حتى مع tuple
و data
).
المحلول
عليك أن تفعل هذا في اثنين من فصول منفصلة لأن Qt هو امتداد إلى c++ (إشارات, فتحات, الخ.) لا تلعب بشكل جيد مع القوالب.الأساس المنطقي و حل هذا يمكن العثور عليها في: http://doc.qt.digia.com/qq/qq15-academic.html
هنا هو مخطط تقريبي من الحل.(هذا يعتمد على رمز نستخدم في التطبيق لدينا و التي تعمل بشكل جيد.)
1.مجردة قائمة الفئة التي لا Qt الاشياء
class FooListModelQt : public QAbstractTableModel {
Q_OBJECT
public:
// Non-template methods, signals, slots, etc. can be used here. For example...
QSet<int> SelectedRows() const;
// ... etc. ...
signals:
void SelectionChanged();
// ... etc. ...
protected:
explicit FooListModelQt(QObject *parent = NULL);
virtual ~FooListModelQt() = 0;
// ... etc. ...
};
2.خلاصة الدرجة التي لا قالب الاشياء
template <typename T>
class FooListModel : public FooListModelQt {
public:
const T* at(int index) const { return items_.at(index); }
int count() const { return items_.count(); }
void Append(T *item);
// ... etc. ...
protected:
explicit FooListModel(QObject *parent = NULL);
virtual ~FooListModel();
private:
QList<T*> items_;
};
3.الفعلية القائمة فئة
class BarListModel : public FooListModel<Bar> {
Q_OBJECT
public:
explicit BarListModel(QObject *parent = NULL);
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
// ... etc. ...
};
نصائح أخرى
عادة أود أن تنفيذ نموذج بلدي وراثة من QAbstractItemModel
مباشرة وتوفير التنفيذ الخاص بي لوظائف العرض التقديمي مثل data()
للتعامل مع حاوية تخزين البيانات أعطي النموذج.
إذا كان لديك تكرار التعليمات البرمجية للاستخدام QList<T>
و std::vector<T>
ثم أود أن أقترح تحويل واحد إلى الآخر عن طريق القيام إما:
QList<T> list = QList::fromVector(QVector::fromStdVector(vector));
أو في الاتجاه الآخر.
std::vector<T> vector = qlist.toVector().toStdVector();
كنت تفعل هذا الأخير ولكن يمكنك اختيار إما.
بناء على تعليقاتك الإضافية هناك 2 مسارات العمل التي يمكنك اتخاذها:
المسار 1:
تنفيذ objectA
و objectB
على النحو التالي:
class objectA : baseObject
و
class objectB : baseObject
أين baseObject
هو:
struct baseObject
{
virtual std::string toString() = 0;
};
ربما أسهل للتحويل إلى سلسلة ثم أي شيء آخر.
سيشمل المسار 2 بشكل أساسي داخل النموذج باستخدام std::vector<boost::any>()
كحاوية تخزين البيانات الخاصة بك ، وبهذه الطريقة يمكنك تنفيذ فئة فرعية نموذج واحد QAbstractListModel
.
الشيء الذي عليك أن تنظر أنه إذا حاوية تخزين البيانات الخاصة بك يمكنك ربما جعل المشترك عرض البيانات التي تقتصر على ما يمكنك القيام به ل data()
وظيفة من شأنها أن تعطي وجهة نظرك العنصر لديه للعودة QVariant
وانها محدودة في ما يمكنك بناء عليه من.