不同的数据结构体共用一份Model/View
@data.h@
#pragma once
#include <QSharedPointer>
#include <QVariant>
#include <QList>
#include <QMap>
template<class CT>
class AbstractMember
{
public:
typedef QSharedPointer<AbstractMember<CT>> M_Ptr;
//@获取d的成员值
virtual QVariant GetValue(const CT& d) const = 0;
//@设置d的成员值
virtual void SetValue(CT &d, const QVariant &var) = 0;
};
template<class CT, class MT>
class Member : public AbstractMember<CT>
{
public:
Member(MT CT::*p) :m_pPtr(p) {}
QVariant GetValue(const CT& d) const
{
return QVariant::fromValue<MT>(d.*m_pPtr);
}
void SetValue(CT &d, const QVariant &var)
{
d.*m_pPtr = var.value<MT>();
}
private:
MT CT::*m_pPtr;
};
template<class CT>
class DataField
{
public:
DataField() { init(); }
//@获取d的第index个成员值
QVariant GetValue(const CT &d, int index) const
{
QVariant var;
if (m_mFields.contains(index))
var = m_mFields[index]->GetValue(d);
return var;
}
//@设置d的第index个成员值
bool SetValue(CT &d, int index, const QVariant &var)
{
if (m_mFields.contains(index))
{
m_mFields[index]->SetValue(d, var);
return true;
}
return false;
}
//@获取数据结构体第index个成员的中文名称
QString GetName(int index) const
{
QString name;
if (m_mNames.contains(index))
name = m_mNames[index];
return name;
}
//@获取数据结构体的成员数量
int GetFieldCount()const
{
return m_mFields.count();
}
//@定义数据结构体成员
template<typename MT>
void defineMember(MT CT::*p, int index)
{
AbstractMember<CT>::M_Ptr ptr(new Member<CT, MT>(p));
m_mFields[index] = ptr;
}
//@定义数据结构体成员中文名
void defineName(QString name, int index)
{
m_mNames[index] = name;
}
private:
//@初始化数据结构体信息,包括不限于定义成员及成员的中文名
void init();
private:
QMap<int, typename AbstractMember<CT>::M_Ptr> m_mFields;
QMap<int, QString> m_mNames;
};
Model部分
/*@AbstractModel.h@*/
#pragma once
#include <QAbstractItemModel>
#include <QList>
#include "data.h"
template<class CT>
class AbstractModel : public QAbstractItemModel
{
public:
AbstractModel(QObject *parent = 0) {}
virtual QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const;
virtual QModelIndex parent(const QModelIndex &child) const;
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
//@插入一行数据
void InsertData(const CT &d);
//@插入多行数据
void InsertDatas(const QList<CT> ds);
private:
QList<CT> m_lDatas;
DataField<CT> m_dField;
};
template<class CT>
inline QModelIndex AbstractModel<CT>::index(int row, int column, const QModelIndex & parent) const
{
return createIndex(row,column);
}
template<class CT>
inline QModelIndex AbstractModel<CT>::parent(const QModelIndex & child) const
{
return QModelIndex();
}
template<class CT>
inline int AbstractModel<CT>::rowCount(const QModelIndex & parent) const
{
return m_lDatas.count();
}
template<class CT>
inline int AbstractModel<CT>::columnCount(const QModelIndex & parent) const
{
return m_dField.GetFieldCount();
}
template<class CT>
inline QVariant AbstractModel<CT>::data(const QModelIndex & index, int role) const
{
QVariant var;
if (index.isValid())
{
int row = index.row();
int col = index.column();
if (role == Qt::DisplayRole)
{
var = m_dField.GetValue(m_lDatas[row], col);
}
else if (role == Qt::EditRole)
{
var = m_dField.GetValue(m_lDatas[row], col);
}
}
return var;
}
template<class CT>
inline bool AbstractModel<CT>::setData(const QModelIndex & index, const QVariant & value, int role)
{
if (index.isValid)
{
if (role == Qt::EditRole)
{
int row = index.row();
int col = index.column();
return m_dField.SetValue(m_lDatas[row], col, value);
}
}
return QAbstractItemModel::setData(index,value,role);
}
template<class CT>
inline QVariant AbstractModel<CT>::headerData(int section, Qt::Orientation orientation, int role) const
{
QVariant var;
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
{
var = m_dField.GetName(section);
}
return var;
}
template<class CT>
inline Qt::ItemFlags AbstractModel<CT>::flags(const QModelIndex & index) const
{
Qt::ItemFlag flags = QAbstractItemModel::flags(index);
if (index.isValid())
flags = Qt::ItemIsEditable;
return flags;
}
template<class CT>
inline void AbstractModel<CT>::InsertData(const CT & d)
{
beginResetModel();
m_lDatas.append(d);
endResetModel();
}
template<class CT>
inline void AbstractModel<CT>::InsertDatas(const QList<CT> ds)
{
beginResetModel();
m_lDatas.append(ds);
endResetModel();
}
数据结构体定义示例
/*@ClassA.h@*/
#pragma once
#include "data.h"
class ClassA
{
public:
QString name;
QString sex;
int grade;
double gradeCount;
};
template<>
void DataField<ClassA>::init();
/*@ClassA.cpp@*/
#include "ClassA.h"
template<>
void DataField<ClassA>::init()
{
defineMember(&ClassA::name, 0);
defineMember(&ClassA::sex, 1);
defineMember(&ClassA::grade, 2);
defineMember(&ClassA::gradeCount, 3);
defineName(QStringLiteral("姓名"), 0);
defineName(QStringLiteral("性别"), 1);
defineName(QStringLiteral("年级"), 2);
defineName(QStringLiteral("分数"), 3);
}