话不多说,直接看代码
一、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 // 0return 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_OBJECTpublic: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();
}