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();
}