QT Model/View结合模板创建Table

这篇博客探讨了如何在QT中利用Model/View框架结合模板,实现不同数据结构体共享同一Model/View,从而高效地展示表格数据。
摘要由CSDN通过智能技术生成

不同的数据结构体共用一份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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值