QAbstractTableModel 与 QTableView 结合使用。具体怎么用

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#pragma once
#include <QAbstractTableModel>

#pragma execution_character_set("utf-8") // qt支持显示中文

enum COLUMN_HEAD_INDEX {
	No = 0,
	Reference = 1,
	X = 2,
	Y = 3,
	Z = 4,
	R = 5,
	Part = 6,
	Feeder = 7,
	Nozzle = 8,
	HD = 9,
	CS = 10,
	CY = 11,
	SK = 12,
	AR = 13,
	FID = 14,
	BL = 15,
	COLUMN = 16
};


class TableModel : public QAbstractTableModel {

public:
	TableModel(QAbstractTableModel *parent = nullptr);
	~TableModel();

	
	// 返回行个数
	virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
	// 返回列个数
	virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
	// 返回头文本
	virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
	// 返回索引数据
	virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
	// 返回模型索引
	virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
	// 返回模型索引的编辑方式
	virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
	// 设置模型索引数据
	virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
	// 插入行
	virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
	// 删除行
	virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;




private:
	// 16列,对应16个链表存储数据
	QStringList m_No;
	QStringList m_Reference;
	QStringList m_X;
	QStringList m_Y;
	QStringList m_Z;
	QStringList m_R;
	QStringList m_Part;
	QStringList m_Feeder;
	QStringList m_Nozzle;
	QStringList m_HD;
	QMap<int, Qt::CheckState> m_CS;
	QStringList m_CY;
	QMap<int, Qt::CheckState> m_SK;
	QStringList m_AR;
	QMap<int, Qt::CheckState> m_FID;
	QStringList m_BL;

	// 存储水平方向头数据
	QStringList m_HorizontalHead;
};

#include "TableModel.h"

TableModel::TableModel(QAbstractTableModel *parent) : QAbstractTableModel(parent) {
	this->m_HorizontalHead.append("No.");
	this->m_HorizontalHead.append("Reference");
	this->m_HorizontalHead.append("X");
	this->m_HorizontalHead.append("Y");
	this->m_HorizontalHead.append("Z");
	this->m_HorizontalHead.append("R");
	this->m_HorizontalHead.append("Part");
	this->m_HorizontalHead.append("Feeder");
	this->m_HorizontalHead.append("Nozzle");
	this->m_HorizontalHead.append("HD");
	this->m_HorizontalHead.append("CS");
	this->m_HorizontalHead.append("CY");
	this->m_HorizontalHead.append("SK");
	this->m_HorizontalHead.append("AR");
	this->m_HorizontalHead.append("FID");
	this->m_HorizontalHead.append("BL");
}

TableModel::~TableModel() {

}


// 返回行个数
int TableModel::rowCount(const QModelIndex &parent) const {
	return this->m_No.size();
}


// 返回列个数
int TableModel::columnCount(const QModelIndex &parent) const {
	return COLUMN_HEAD_INDEX::COLUMN;
}


// 返回头文本
QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const {
	if (role != Qt::DisplayRole) // 返回一个默认数据的表头
		return QAbstractTableModel::headerData(section, orientation, role);


	if (orientation == Qt::Orientation::Horizontal) {
		return this->m_HorizontalHead[section];
	}

	return QAbstractTableModel::headerData(section, orientation, role);
}


// 返回索引数据
QVariant TableModel::data(const QModelIndex &index, int role) const {
	// 不存在则返回默认
	if (!index.isValid()) return QVariant();

	if (role == Qt::DisplayRole || role == Qt::EditRole) {
		switch (index.column()) {
			case COLUMN_HEAD_INDEX::No:
				return this->m_No[index.row()];
				break;

			case COLUMN_HEAD_INDEX::Reference:
				return this->m_Reference[index.row()];
				break;

			case COLUMN_HEAD_INDEX::X:
				return this->m_X[index.row()];
				break;

			case COLUMN_HEAD_INDEX::Y:
				return this->m_Y[index.row()];
				break;

			case COLUMN_HEAD_INDEX::Z:
				return this->m_Z[index.row()];
				break;

			case COLUMN_HEAD_INDEX::R:
				return this->m_R[index.row()];
				break;

			case COLUMN_HEAD_INDEX::Part:
				return this->m_Part[index.row()];
				break;

			case COLUMN_HEAD_INDEX::Feeder:
				return this->m_Feeder[index.row()];
				break;

			case COLUMN_HEAD_INDEX::Nozzle:
				return this->m_Nozzle[index.row()];
				break;

			case COLUMN_HEAD_INDEX::HD:
				return this->m_HD[index.row()];
				break;

			case COLUMN_HEAD_INDEX::CY:
				return this->m_CY[index.row()];
				break;

			case COLUMN_HEAD_INDEX::AR:
				return this->m_AR[index.row()];
				break;

			case COLUMN_HEAD_INDEX::BL:
				return this->m_BL[index.row()];

			default:
				return QVariant();
				break;
		}
	} else if (role == Qt::CheckStateRole) {
		switch (index.column()) {
			case COLUMN_HEAD_INDEX::CS:
				return this->m_CS[index.row()] == Qt::Checked ? Qt::Checked : Qt::Unchecked;
				break;

			case COLUMN_HEAD_INDEX::SK:
				return this->m_SK[index.row()] == Qt::Checked ? Qt::Checked : Qt::Unchecked;
				break;

			case COLUMN_HEAD_INDEX::FID:
				return this->m_FID[index.row()] == Qt::Checked ? Qt::Checked : Qt::Unchecked;
				break;

			default:
				return QVariant();
				break;
		}
	}

	return QVariant();
}



// 返回模型索引
QModelIndex TableModel::index(int row, int column, const QModelIndex &parent) const {
	// 行和列的合法性检查
	if (row < 0 || row >= this->m_No.size() || column < 0 || column >= COLUMN_HEAD_INDEX::COLUMN) {
		return QModelIndex();
	}

	switch (column) {
		case COLUMN_HEAD_INDEX::No:
			// 获取对应行和列单元格的数据
			//QString str = this->m_No[row];
			// 新建一个索引并绑定指针数据返回
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::Reference:
			//QString str = this->m_Reference[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::X:
			//QString str = this->m_X[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::Y:
			//QString str = this->m_Y[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::Z:
			//QString str = this->m_Z[row];
			return createIndex(row, column/*, &str*/);
			break;
		case COLUMN_HEAD_INDEX::R:
			//QString str = this->m_R[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::Part:
			//QString str = this->m_Part[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::Feeder:
			//QString str = this->m_Feeder[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::Nozzle:
			//QString str = this->m_Nozzle[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::HD:
			//QString str = this->m_HD[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::CS:
			//QString str = this->m_CS[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::CY:
			//QString str = this->m_CY[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::SK:
			//QString str = this->m_SK[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::AR:
			//QString str = this->m_AR[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::FID:
			//QString str = this->m_FID[row];
			return createIndex(row, column/*, &str*/);
			break;

		case COLUMN_HEAD_INDEX::BL:
			//QString str = this->m_BL[row];
			return createIndex(row, column/*, &str*/);
			break;

		default:
			return createIndex(row, column);
			break;
	}

	return createIndex(row, column);
}



// 返回模型索引的编辑方式
Qt::ItemFlags TableModel::flags(const QModelIndex &index) const {
	if (!index.isValid()) {
		// 返回用户可以与界面进行交互
		return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
	}

	switch (index.column()) {
		case COLUMN_HEAD_INDEX::No:
			// 返回用户可以与界面进行交互
			return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::Reference:
			// 返回用户可以进行编辑
			return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::X:
			return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::Y:
			return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::Z:
			return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::R:
			return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::Part:
			return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::Feeder:
			return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::Nozzle:
			return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::HD:
			return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::CS:
			return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
			break;

		case COLUMN_HEAD_INDEX::CY:
			return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::SK:
			return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
			break;

		case COLUMN_HEAD_INDEX::AR:
			return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
			break;

		case COLUMN_HEAD_INDEX::FID:
			return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
			break;

		case COLUMN_HEAD_INDEX::BL:
			return Qt::ItemIsEnabled | Qt::ItemIsSelectable;

		default:
			return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
			break;
	}


	return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}



// 设置模型索引数据
bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
	if (index.isValid() && role == Qt::EditRole) {
		switch (index.column()) {
			case COLUMN_HEAD_INDEX::No:
				this->m_No[index.row()] = value.toString();
				break;

			case COLUMN_HEAD_INDEX::Reference:
				this->m_Reference[index.row()] = value.toString();
				break;

			case COLUMN_HEAD_INDEX::X:
				this->m_X[index.row()] = value.toString();
				break;

			case COLUMN_HEAD_INDEX::Y:
				this->m_Y[index.row()] = value.toString();
				break;

			case COLUMN_HEAD_INDEX::Z:
				this->m_Z[index.row()] = value.toString();
				break;

			case COLUMN_HEAD_INDEX::R:
				this->m_R[index.row()] = value.toString();
				break;

			case COLUMN_HEAD_INDEX::Part:
				this->m_Part[index.row()] = value.toString();
				break;

			case COLUMN_HEAD_INDEX::Feeder:
				this->m_Feeder[index.row()] = value.toString();
				break;

			case COLUMN_HEAD_INDEX::Nozzle:
				this->m_Nozzle[index.row()] = value.toString();
				break;

			case COLUMN_HEAD_INDEX::HD:
				this->m_HD[index.row()] = value.toString();
				break;

			//case COLUMN_HEAD_INDEX::CS:
			//	//this->m_CS[index.row()] = value.toString();
			//	this->m_CS[index.row()] = (value.toInt() == Qt::Checked ? Qt::Checked : Qt::Unchecked);
			//	break;

			case COLUMN_HEAD_INDEX::CY:
				this->m_CY[index.row()] = value.toString();
				break;

			/*case COLUMN_HEAD_INDEX::SK:
				this->m_SK[index.row()] = value.toString();
				break;*/

			case COLUMN_HEAD_INDEX::AR:
				this->m_AR[index.row()] = value.toString();
				break;

			/*case COLUMN_HEAD_INDEX::FID:
				this->m_FID[index.row()] = value.toString();
				break;*/

			case COLUMN_HEAD_INDEX::BL:
				this->m_BL[index.row()] = value.toString();

			default:
				break;
		}


		// 设置完成后发射信号告诉视图数据有修改
		emit dataChanged(index, index);	// 参数是左上角和右下角的模型索引(这里是相同的)

		return true;

	} else if (index.isValid() && role == Qt::CheckStateRole) {
		switch (index.column()) {
				case COLUMN_HEAD_INDEX::CS:
					this->m_CS[index.row()] = (value.toInt() == Qt::Checked ? Qt::Checked : Qt::Unchecked);
					break;

				case COLUMN_HEAD_INDEX::SK:
					this->m_SK[index.row()] = (value.toInt() == Qt::Checked ? Qt::Checked : Qt::Unchecked);
					break;

				case COLUMN_HEAD_INDEX::FID:
					this->m_FID[index.row()] = (value.toInt() == Qt::Checked ? Qt::Checked : Qt::Unchecked);
					break;

			default:
				break;
		}


		// 设置完成后发射信号告诉视图数据有修改
		emit dataChanged(index, index);	// 参数是左上角和右下角的模型索引(这里是相同的)

		return true;
	}

	return false;
}



// 插入行	参数:插入的位置;插入的行数;父项的模型索引
bool TableModel::insertRows(int row, int count, const QModelIndex &parent) {
	// 如果插入零行,则返回false,表示插入失败
	if (count == 0) return false;

	// 没有父类
	if (!parent.isValid()) {
		// 从row开始插入行,直到row + count - 1处
		beginInsertRows(QModelIndex(), row, row + count - 1);

		// 有父类
	} else {
		// 从row开始插入行,直到row + count - 1处
		beginInsertRows(parent, row, row + count - 1);
	}

	// 按照位置在链表对应位置进行插入数据
	for (int addCount = 0; addCount < count; addCount++) {
		this->m_No.insert(row + addCount, "");
		this->m_Reference.insert(row + addCount, "");
		this->m_X.insert(row + addCount, "");
		this->m_Y.insert(row + addCount, "");
		this->m_Z.insert(row + addCount, "");
		this->m_R.insert(row + addCount, "");
		this->m_Part.insert(row + addCount, "");
		this->m_Feeder.insert(row + addCount, "");
		this->m_Nozzle.insert(row + addCount, "");
		this->m_HD.insert(row + addCount, "");
		this->m_CS.insert(row + addCount, Qt::CheckState::Unchecked);
		this->m_CY.insert(row + addCount, "");
		this->m_SK.insert(row + addCount, Qt::CheckState::Unchecked);
		this->m_AR.insert(row + addCount, "");
		this->m_FID.insert(row + addCount, Qt::CheckState::Unchecked);
		this->m_BL.insert(row + addCount, "");
	}


	// 结束插入行
	endInsertRows();


	return true;
}



// 删除行
bool TableModel::removeRows(int row, int count, const QModelIndex &parent) {
	if (count == 0) return false;

	if (!parent.isValid()) {
		beginRemoveRows(QModelIndex(), row, row + count - 1);
	} else {
		beginInsertRows(parent, row, row + count - 1);
	}

	// 按照位置在链表对应位置进行移除数据
	for (int removeCount = 0; removeCount < count; removeCount++) {
		this->m_No.removeAt(row);
		this->m_Reference.removeAt(row);
		this->m_X.removeAt(row);
		this->m_Y.removeAt(row);
		this->m_Z.removeAt(row);
		this->m_R.removeAt(row);
		this->m_Part.removeAt(row);
		this->m_Feeder.removeAt(row);
		this->m_Nozzle.removeAt(row);
		this->m_HD.removeAt(row);
		this->m_CS.remove(row + removeCount);
		this->m_CY.removeAt(row);
		this->m_SK.remove(row + removeCount);
		this->m_AR.removeAt(row);
		this->m_FID.remove(row + removeCount);
		this->m_BL.removeAt(row);
	}

	endRemoveRows();


	return true;
}

对于QTableView的优化,有几个方面可以考虑: 1. 数据模型优化:使用QAbstractTableModel作为数据模型,重写rowCount、columnCount和data等方法,以提高数据获取的效率。可以考虑使用Qt的容器类如QList或QVector来存储数据,以便快速访问和更新。 2. 视图渲染优化:对于大量数据的情况,可以考虑使用Qt的视图委托(QItemDelegate)来进行定制化绘制,并避免不必要的重绘操作。此外,可以通过调整QTableView的渲染属性和样式表来提高视图的渲染速度。 3. 数据刷新优化:当数据变化时,可以使用QModelIndexList来标记需要刷新的单元格,而不是全表刷新。同时,可以使用beginInsertRows、endInsertRows、beginRemoveRows和endRemoveRows等方法来告知视图数据的变化范围,以提高刷新效率。 4. 数据过滤与排序优化:当需要对数据进行过滤或排序时,可以在模型中实现相应的方法,并结合QSortFilterProxyModel来进行快速过滤和排序操作,避免直接对原始数据进行频繁操作。 5. 异步加载数据:对于大量数据的加载,可以考虑使用异步方式进行,以避免界面阻塞。可以通过多线程、Qt的信号与槽机制或QtConcurrent等方式来实现异步加载。 6. 内存管理:在处理大量数据时,注意及时释放不再使用的资源,避免内存占用过高。可以使用Qt的内存管理工具来进行内存泄漏检测和性能分析。 通过以上一些优化措施,可以提高QTableView的性能和用户体验。当然,具体优化策略还需根据实际应用场景和具体需求来进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值