QAbstractItemModel 与QTableView搭配使用实现一个记录学生id、姓名、分数的一个表格,并且表头支持勾选,输出c++代码
时间: 2023-11-22 20:57:05 浏览: 86
以下是一个简单的示例代码,实现了一个表格模型并在 QTableView 中显示。其中表头支持勾选功能,勾选后会将整列数据进行操作(这里是将分数全部加 10)。
```cpp
#include <QAbstractItemModel>
#include <QTableView>
#include <QHeaderView>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QCheckBox>
class StudentModel : public QAbstractItemModel {
public:
enum {
ID = 0,
NAME,
SCORE,
COLUMN_COUNT
};
StudentModel(QObject* parent = nullptr)
: QAbstractItemModel(parent)
{
// 初始化表头数据
m_headerData << tr("ID") << tr("Name") << tr("Score");
}
// 实现父类的纯虚函数,返回数据的索引
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override {
if (!hasIndex(row, column, parent)) {
return QModelIndex();
}
if (!parent.isValid()) {
// 如果 parent 无效,说明查询的是根节点,返回第 row 行第 column 列的索引
return createIndex(row, column);
}
// 否则返回 parent 的第 row 行第 column 列的子节点索引
QStandardItem* parentItem = static_cast<QStandardItem*>(parent.internalPointer());
return createIndex(row, column, parentItem->child(row, column));
}
// 实现父类的纯虚函数,返回父节点的索引
QModelIndex parent(const QModelIndex& index) const override {
if (!index.isValid()) {
return QModelIndex();
}
QStandardItem* item = static_cast<QStandardItem*>(index.internalPointer());
QStandardItem* parentItem = item->parent();
if (parentItem == m_rootItem) {
return QModelIndex();
}
return createIndex(parentItem->row(), 0, parentItem);
}
// 实现父类的纯虚函数,返回每个索引对应的数据
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override {
if (!index.isValid()) {
return QVariant();
}
QStandardItem* item = static_cast<QStandardItem*>(index.internalPointer());
if (role == Qt::DisplayRole || role == Qt::EditRole) {
return item->data();
}
return QVariant();
}
// 实现父类的纯虚函数,设置每个索引对应的数据
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override {
if (!index.isValid() || role != Qt::EditRole) {
return false;
}
QStandardItem* item = static_cast<QStandardItem*>(index.internalPointer());
item->setData(value);
emit dataChanged(index, index);
return true;
}
// 实现父类的纯虚函数,返回每个索引的标志位
Qt::ItemFlags flags(const QModelIndex& index) const override {
if (!index.isValid()) {
return Qt::NoItemFlags;
}
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if (index.column() == SCORE) {
flags |= Qt::ItemIsEditable;
}
return flags;
}
// 实现父类的纯虚函数,返回每一列的头数据
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override {
if (role != Qt::DisplayRole) {
return QVariant();
}
if (orientation == Qt::Horizontal) {
// 如果是表头,返回对应的表头数据
return m_headerData.value(section);
} else {
// 如果是行头,返回行号
return section + 1;
}
}
// 实现父类的纯虚函数,返回每个节点的行数和列数
int rowCount(const QModelIndex& parent = QModelIndex()) const override {
if (!parent.isValid()) {
return m_rootItem->rowCount();
}
QStandardItem* item = static_cast<QStandardItem*>(parent.internalPointer());
return item->rowCount();
}
int columnCount(const QModelIndex& parent = QModelIndex()) const override {
Q_UNUSED(parent)
return COLUMN_COUNT;
}
// 设置表格数据
void setStudentData(const QList<QList<QVariant>>& data) {
// 清空原有数据
if (m_rootItem) {
delete m_rootItem;
}
m_rootItem = new QStandardItem(tr("Root"));
// 添加新数据
for (int i = 0; i < data.size(); ++i) {
QList<QVariant> rowData = data.at(i);
QList<QStandardItem*> items;
for (int j = 0; j < rowData.size(); ++j) {
QStandardItem* item = new QStandardItem(rowData.at(j).toString());
items << item;
}
m_rootItem->appendRow(items);
}
}
// 全选/取消全选
void selectAll(bool checked) {
for (int i = 0; i < rowCount(); ++i) {
QModelIndex index = createIndex(i, SCORE);
setData(index, checked ? (data(index).toInt() + 10) : (data(index).toInt() - 10));
}
}
private:
QStandardItem* m_rootItem = nullptr;
QStringList m_headerData;
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 创建表格模型
StudentModel* model = new StudentModel();
// 设置表格数据
QList<QList<QVariant>> data = {
{ 1, "Alice", 80 },
{ 2, "Bob", 90 },
{ 3, "Charlie", 70 },
{ 4, "David", 85 }
};
model->setStudentData(data);
// 创建表视图
QTableView* view = new QTableView();
view->setModel(model);
view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
view->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
view->verticalHeader()->setDefaultSectionSize(25);
// 在表头添加全选按钮
QWidget* headerWidget = new QWidget();
QHBoxLayout* layout = new QHBoxLayout(headerWidget);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
QCheckBox* checkBox = new QCheckBox();
checkBox->setTristate(true);
checkBox->setCheckState(Qt::PartiallyChecked);
connect(checkBox, &QCheckBox::stateChanged, model, &StudentModel::selectAll);
QLabel* label = new QLabel(tr("Score"));
label->setAlignment(Qt::AlignCenter);
layout->addWidget(checkBox);
layout->addWidget(label);
view->setCornerWidget(headerWidget);
// 显示窗口
view->show();
return app.exec();
}
```
阅读全文