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

QT中QTableView+Model+Delegate实现一个demo

一、概述

功能: 实现一个查询学生信息的表格,有学号、性别、年龄、班级和分数共5列,针对最后一列分数实现委托代理,要求能编辑和查看该分数列。

QTableView实现视图展示ui

Model负责数据的构造

Delegate是委托,可针对某列数据做自定义扩展

使用的qt控件如下:

  • QTableView
  • StudentTableModel继承自QAbstractTableModel
  • ScoreDelegate继承自QStyledItemDelegate

二、具体代码

studenttablemodel.h

#ifndef STUDENTTABLEMODEL_H
#define STUDENTTABLEMODEL_H#include <QAbstractTableModel>
#include <QObject>class StudentTableModel : public QAbstractTableModel
{Q_OBJECT
public:explicit StudentTableModel(QObject *parent = nullptr);int rowCount(const QModelIndex &parent = QModelIndex()) const override;int columnCount(const QModelIndex &parent = QModelIndex()) const override;QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override;bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;Qt::ItemFlags flags(const QModelIndex &index) const override;private:QVector<QVector<QVariant>> m_data; // 数据存储
};#endif // STUDENTTABLEMODEL_H

studenttablemodel.cpp

#include "studenttablemodel.h"StudentTableModel::StudentTableModel(QObject *parent): QAbstractTableModel{parent}
{// 初始化示例数据m_data = {{"1001", "male", 18, "class_01", 85},{"1002", "female", 19, "class_02", 92},{"1003", "male", 20, "class_03", 78}};
}int StudentTableModel::rowCount(const QModelIndex &parent) const
{Q_UNUSED(parent);return m_data.size();
}int StudentTableModel::columnCount(const QModelIndex &parent) const
{Q_UNUSED(parent);return 5; // 学号、性别、年龄、班级、分数
}QVariant StudentTableModel::data(const QModelIndex &index, int role) const
{if(!index.isValid()) return QVariant();if (role == Qt::DisplayRole || role == Qt::EditRole) {return m_data[index.row()][index.column()];}return QVariant();
}QVariant StudentTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {switch (section) {case 0: return "id";case 1: return "sex";case 2: return "age";case 3: return "class";case 4: return "score";}}return QVariant();
}bool StudentTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{if (role == Qt::EditRole && index.isValid()) {m_data[index.row()][index.column()] = value;emit dataChanged(index, index); // 通知视图更新return true;}return false;
}Qt::ItemFlags StudentTableModel::flags(const QModelIndex &index) const
{auto flags = QAbstractTableModel::flags(index);if (index.column() == 4) // 分数列可编辑flags |= Qt::ItemIsEditable;return flags;
}

scoredelegate.h

#ifndef SCOREDELEGATE_H
#define SCOREDELEGATE_H#include <QObject>
#include <QStyledItemDelegate>class ScoreDelegate : public QStyledItemDelegate
{Q_OBJECT
public:explicit ScoreDelegate(QObject *parent = nullptr);QWidget *createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index) const override;void setEditorData(QWidget *editor, const QModelIndex &index) const override;void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const override;
};#endif // SCOREDELEGATE_H
#include "scoredelegate.h"#include <QSpinBox>ScoreDelegate::ScoreDelegate(QObject *parent): QStyledItemDelegate{parent}
{}QWidget *ScoreDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{if (index.column() == 4) { // 仅对分数列生效QSpinBox *editor = new QSpinBox(parent);editor->setRange(0, 100);editor->setFrame(false);return editor;}return QStyledItemDelegate::createEditor(parent, option, index);
}void ScoreDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{if (index.column() == 4) {int value = index.model()->data(index, Qt::EditRole).toInt();QSpinBox *spinBox = qobject_cast<QSpinBox*>(editor);spinBox->setValue(value);} else {QStyledItemDelegate::setEditorData(editor, index);}
}void ScoreDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{if (index.column() == 4) {QSpinBox *spinBox = qobject_cast<QSpinBox*>(editor);spinBox->interpretText();model->setData(index, spinBox->value());} else {QStyledItemDelegate::setModelData(editor, model, index);}
}

widget.cpp

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);model = new StudentTableModel(this);scoreDelegate = new ScoreDelegate(this);ui->tableView->setModel(this->model);ui->tableView->setItemDelegateForColumn(4, scoreDelegate);// 表格样式设置ui->tableView->verticalHeader()->hide();ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);ui->tableView->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);//手动设置show显示ui->tableView->show();
}

三、遇到问题总结

1、QTableView展示不出来,model+tableview为局部变量

 当构造函数执行结束时,这两个对象会被自动销毁。即使调用了 tableView.show(),窗口会短暂显示,但对象销毁后视图也随之消失,因此实际看不到表格

    解决方案​:
将 tableView 和 model ​提升为类的成员变量,确保其生命周期与窗口一致:

2、 ​视图未嵌入父窗口布局

问题分析​:

  • 即使解决了生命周期问题,若 tableView 未添加到窗口布局中,它可能因尺寸为0或位置错误而不可见。
  • 你的代码中 tableView 是独立创建的,未关联到 ui 生成的界面布局中。

解决方案​:
将 tableView 添加到窗口的布局管理器中(例如使用 QVBoxLayout):

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

相关文章:

  • TikTok 视频审核模型:用逻辑回归找出特殊类型的视频
  • 全栈:SSH和SSM和Springboot mybatisplus有什么区别?
  • 以ros的docker镜像为例,探讨docker镜像的使用
  • 力扣刷题日常(7-8)
  • 【Arch-Linux,hyprland】常用配置-已实验成功指令大全(自用)(持续更新)
  • 如何保证数据库的持久性与一致性:从 Linux 磁盘缓存策略到 MySQL 的设计
  • 执业药师证识别技术:医药健康生态中发挥愈发关键的作用
  • 微软:科技领域的创新巨头
  • Sleeping Cup 论坛:连接开发者与创新的桥梁
  • 隧道COVI检测器的用处
  • [SKE]使用OpenSSL库实现AES、SM4、DES、RSA、3DES_EDE和3DES_EEE算法的加解密验证
  • SringBoot入门
  • Linux启动防火墙提示提示 Active: failed (Result: timeout)
  • Golang 指针与引用深度解析:对比 C/C++ 的内存管理哲学
  • Jupyter Notebook安装使用
  • Javascript对象合并
  • Centos7 | 防火墙(firewalld)使用ipset管理ip地址的集合
  • MySQL 读写分离(含示例代码)
  • 新注册企业信息查询“数据大集网”:驱动企业增长的源头活水
  • 10 卷积神经网络
  • LLMs之Agent:GLM-4.5的简介、安装和使用方法、案例应用之详细攻略
  • 51单片机入门:数码管原理介绍及C代码实现
  • 【硬件】元器件选型
  • 【ESP32设备通信】-LAN8720与ESP32集成
  • 订阅区块,部署合约,加载合约
  • Akamai CloudTest before 60 2025.06.02 XXE注入导致文件包含漏洞(CVE-2025-49493)
  • MOEA/DD(多目标进化算法基于分解)简介
  • AAAI‘26 | 聚焦人工智能前沿:西工大李学龙教授荣任赞助主席,论文取号逼近三万,精彩不容错过!
  • Javaweb———HTTP响应头属性讲解
  • Redis实现数据传输简介