当前位置: 首页 > news >正文

Qt QTableView QAbstractTableModel实现复选框+代理实现单元格编辑

话不多说,直接看代码

一、Model

1、QTableModel_Test.h

#pragma once

#include <QAbstractTableModel>
#include <QObject>
#include <QModelIndex>

class QTableModel_Test  : public QAbstractTableModel
{
	Q_OBJECT
public:
	QTableModel_Test(QObject *parent);
	~QTableModel_Test();

	int rowCount(const QModelIndex & parent) const override;

	int columnCount(const QModelIndex & parent) const override;

	QVariant data(const QModelIndex & index, int role) const override;

	bool setData(const QModelIndex & index, const QVariant & value, int role) override;

	Qt::ItemFlags flags(const QModelIndex & index) const override;

private:
	QList<Qt::CheckState> m_checkBoxStates; // 用于存储复选框状态
	QList<QStringList> m_itemList;
};

2、QTableModel_Test.cpp

#include "QTableModel_Test.h"

QTableModel_Test::QTableModel_Test(QObject *parent)
	: QAbstractTableModel(parent)
{
	// 初始化复选框状态
	for (int i = 0; i < 5; ++i)
	{
		m_checkBoxStates.append(Qt::Unchecked);
		QStringList tempList;
		for (int j = 0; j < 3; ++j)
		{
			tempList.append(QString("item%1%2").arg(i).arg(j));
		}
		m_itemList.append(tempList);
	}
}

QTableModel_Test::~QTableModel_Test()
{}

// 返回行数
int QTableModel_Test::rowCount(const QModelIndex &parent = QModelIndex()) const 
{
	return 5; // 示例中显示5行
}

// 返回列数
int QTableModel_Test::columnCount(const QModelIndex &parent = QModelIndex()) const 
{
	return 3; // 示例中显示3列
}

// 返回数据
QVariant QTableModel_Test::data(const QModelIndex &index, int role) const 
{
	if (!index.isValid()
		||m_itemList.count() <= index.row())
	{
		return QVariant();
	}
	QStringList tempList = m_itemList.at(index.row());
	if (tempList.count() <= index.column())
	{
		return QVariant();
	}

#if 1
	// 第一列显示复选框(关键)
	if (index.column() == 0)
	{
		if (role == Qt::CheckStateRole)
		{
			return m_checkBoxStates[index.row()];
		}
	}

	// 第二列显示普通文本
	if (index.column() >= 0 && role == Qt::DisplayRole)
	{
		QString str = m_itemList[index.row()][index.column()];
		return str;
		//return QString("Item %1").arg(index.row());
	}
#else
	// 第一列显示复选框
	if (index.column() == 0 && role == Qt::CheckStateRole)
	{
		return m_checkBoxStates[index.row()];
	}

	// 第二列显示普通文本
	if (index.column() == 1 && role == Qt::DisplayRole)
	{
		return QString("Item %1").arg(index.row());
	}

#endif // 0

	return QVariant();
}

// 设置数据
bool QTableModel_Test::setData(const QModelIndex &index, const QVariant &value, int role) 
{
	if (!index.isValid())
	{
		return false;
	}

	// 更新复选框状态
	if (index.column() == 0 && role == Qt::CheckStateRole)
	{
		m_checkBoxStates[index.row()] = value.toBool() ? Qt::Checked : Qt::Unchecked;
		emit dataChanged(index, index, { Qt::CheckStateRole });
		return true;
	}
	else
	{//通过代理触发单元格值修改
		m_itemList[index.row()][index.column()]= value.toString();
		emit dataChanged(index, index, { Qt::DisplayRole });
	}
	

	return false;
}

// 返回标志
Qt::ItemFlags QTableModel_Test::flags(const QModelIndex &index) const
{
	if (!index.isValid())
		return Qt::NoItemFlags;

	// 第一列可编辑(用于复选框)
	if (index.column() == 0)
	{
		return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable| Qt::ItemIsEditable;  // 添加可编辑标志;
	}

	return Qt::ItemIsEnabled | Qt::ItemIsSelectable|Qt::ItemIsEditable;  // 添加可编辑标志;
}

二、代理

1、MyDelegate.h

#pragma once

#include <QObject>
#include <QStyleOptionViewItem>
#include <QAbstractItemModel>
#include <QStyledItemDelegate>

class MyDelegate  : public QStyledItemDelegate
{
	Q_OBJECT

public:
	MyDelegate(QObject *parent = nullptr);
	~MyDelegate();

public:
	QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const;
	void setEditorData(QWidget * editor, const QModelIndex & index) const;
	void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
};

2、MyDelegate.cpp

#include "MyDelegate.h"
#include <QLineEdit>

MyDelegate::MyDelegate(QObject *parent)
	: QStyledItemDelegate(parent)
{}

MyDelegate::~MyDelegate()
{}

QWidget* MyDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
	if (index.column() == 1) // 假设第2列需要自定义编辑器
	{
		QLineEdit* editor = new QLineEdit(parent);
		return editor;
	}
	return QStyledItemDelegate::createEditor(parent, option, index);
}

void MyDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
	if (QLineEdit* lineEdit = qobject_cast<QLineEdit*>(editor))
	{
		QString valStr = index.model()->data(index, Qt::EditRole).toString();
		lineEdit->setText(valStr);
	}
	else
	{
		QStyledItemDelegate::setEditorData(editor, index);
	}
}

void MyDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
	if (QLineEdit* lineEdit = qobject_cast<QLineEdit*>(editor))
	{
		QString valStr = lineEdit->text();
		if (valStr.isEmpty())
		{
			return;
		}
		model->setData(index, lineEdit->text(), Qt::EditRole);
	}
	else
	{
		QStyledItemDelegate::setModelData(editor, model, index);
	}
}

三、main.cpp

#include <QApplication>
#include <QTableView>
#include <QAbstractTableModel>
#include "QTableModel_Test.h"
#include "MyDelegate.h"
#include <QHeaderView>
#include <QDebug>

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);

    // 创建模型
	QTableModel_Test *model = new QTableModel_Test(nullptr);

	// 创建视图
	QTableView tableView;
    tableView.setModel(model);

	MyDelegate* delegate = new MyDelegate(nullptr);
	tableView.setItemDelegate(delegate);
	// 设置列宽自适应
	tableView.horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

	// 显示视图
	tableView.show();

	return app.exec();
}

http://www.dtcms.com/a/111596.html

相关文章:

  • 进行性核上性麻痹:饮食调理为健康护航
  • SpringBoot项目报错: 缺少 Validation
  • 【NLP 55、投机采样加速推理】
  • 在线考试系统带万字文档java项目java课程设计java毕业设计springboot项目
  • 【matplotlib参数调整】
  • 2011-2019年各省地方财政国土资源气象等事务支出决策数数据
  • 如何理解缓存一致性?
  • Linux 安装 MySQL8数据库
  • LLM面试题六
  • Linux随机数
  • React: hook相当于函数吗?
  • 算法设计学习9
  • 【Groovy快速上手 ONLY ONE】Groovy与Java的核心差异
  • 常见的ETL工具分类整理
  • 嵌入式——Linux系统的使用以及编程练习
  • stm32+LTR-390UV使用教程含源码
  • 【算法竞赛】dfs+csp综合应用(蓝桥2023A9像素放置)
  • 深入理解时间复杂度与空间复杂度
  • DeepSeek能否用于对话系统(Chatbot)?技术解析与应用实例!
  • 《AI大模型应知应会100篇》第3篇:大模型的能力边界:它能做什么,不能做什么
  • 3.29-3 压力测试(不同用户)
  • 搭建工作流自动化工具n8n并配置deepseek大模型
  • day23学习Pandas库
  • python基础-10-组织文件
  • 6. RabbitMQ 死信队列的详细操作编写
  • linux3 mkdir rmdir rm cp touch ls -d /*/
  • The emulator process for AVD xxx has terminated
  • 部署nerdctl工具
  • A2DP(Advanced Audio Distribution Profile)是蓝牙协议栈中用于音频传输的一个标准化协议
  • Java8 Stream流:过滤、归约与并行计算