インデックス型固有のクラス基底クラスの1つ作成します:
QAbstractItemModel * proxyFactory(IndexType indexType, QObject * parent = 0) {
switch (indexType) {
case Foo::Vector:
return new VectorIndexProxy(parent);
...
}
}
あなたの場合:次に
template <typename Index> class IndexHandler {
};
using VectorIndexHandler = IndexHandler<QVector>;
using HashIndexHandler = IndexHandler<QHash>;
class VectorIndexProxy : public QAbstractItemModel, VectorIndexHandler {
... // should be very small
};
class HashIndexProxy : public QAbstractItemModel, HashIndexHandler {
... // should be very small
};
を代わりにコンストラクタにインデックスタイプを渡し、ファクトリ関数を使用しますQAbstractItemModel
よりも幅広いインターフェースを想定している場合は、そのような基本クラスを作成し、具体的な実装でそれから派生する必要があります。
IndexHandler
のために必要な場合は、それがさらに小さくなって、派生クラスのメソッドを直接呼び出すためにCRTPを使用することができ
:
template <typename Index, typename Derived> class IndexHandler {
Derived * derived() { return static_cast<Derived*>(this); }
const Derived * derived() const; // as above
void foo() {
derived()->setObjectName("Yay");
}
};
class VectorIndexProxy :
public QAbstractItemModel,
public VectorIndexHandler<QVector, VectorIndexProxy>
{
... // should be very small
};
あなたはまた、Qtのスロットであることを基本クラスからメソッドを「促進」することができます
class VectorIndexProxy : ... {
#ifdef Q_MOC_RUN
Q_SLOT void foo();
#endif
};
信号とスロットを持つ基本非QObjectクラスを持つことについては、this questionを参照してください。
最後に、PIMPL idiomを使用して、必要に応じて固定タイプの具体的な実装を行うことができます。ファクトリはコンストラクタで呼び出され、異なるインデックスの異なるPIMPLを交換します。 以降のすべてのQtクラスは、既に動的にPIMPLを割り当てているので、PIMPLをQObjectPrivate
(#include <private/qobject_p.h>
)から派生させ、保護されたQObject(QObjectPrivate&)
にPIMPLのインスタンスを渡すことによって、その割り当てをピギーバックすることができます。このパターンはQtに遍在しているので、実装の詳細であっても、少なくともQt5ではそれほど遠くには通りません。ここではラフスケッチです:
// ProxyModel.cpp
#include <private/qobject_p.h>
class ProxyModelPrivate : public QObjectPrivate {
// Note: you don't need a q-pointer, QObjectData already provides it
// for you! CAVEAT: q-pointer is not valid until the QObject-derived-class's
// constructor has returned. This would be the case even if you passed
// the q-pointer explicitly, of course.
...
}; // base class
class VectorProxyModelPrivate : public ProxyModelPrivate { ... };
class ProxyModel : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(ProxyModel)
ProxyModel * pimpl(IndexType indexType) {
switch (indexType) {
case Vector: return new VectorProxyModelPrivate();
...
}
public:
enum IndexType { Vector, Hash };
explicit ProxyModel(IndexType indexType, QObject *parent = 0) :
QObject(*pimpl(IndexType), parent)
{}
};
あなたはQAbstractItemModel
から導出された場合は、お使いのPIMPLは同じやり方で、QAbstractItemModelPrivate
から派生します。これはQtのQObject
生まれのクラスで動作します!
最初の例の 'VectorIndexProxy'と' HashIndexProxy'クラス定義に 'Q_OBJECT'マクロを必ず含めてください。 –
@JonHarperこれは '...'に暗示されていることです:)そうでなければ、それは滑りやすい斜面です。誰かが私に教えてくれる次のものは、モデルの全体的な正しい実装がそこに属しているということです: –
良い点。 :-) –