qt QAbstractTableModel详解
1、概述
QAbstractTableModel 是 Qt 框架中的一个类,用于在 Qt 应用程序中实现自定义的表格数据模型。它是 Qt 中的一个抽象基类,提供了创建和操作表格数据所需的接口。QAbstractTableModel 为模型提供了一个标准接口,这些模型将其数据表示为二维项目数组,适用于向 QTableView 或 QML 中的 TableView 组件提供数据,用于显示和编辑。
2、重要方法
QAbstractTableModel 中有几个重要的方法需要子类实现或重写,这些方法定义了表格的数据源和结构:
- rowCount():返回表格的行数。
- columnCount():返回表格的列数。
- data(int row, int column, int role = Qt::DisplayRole):返回指定单元格的数据。row 和 column 分别表示行和列的索引,role 表示数据的角色(如显示文本、字体、对齐方式等)。
- headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole):返回表头的数据。section 表示列或行的索引,orientation 表示方向(水平或垂直),role 表示数据的角色。
- flags(const QModelIndex &index) const:返回指定单元格的标志,用于控制单元格是否可编辑、可选择等。
此外,如果模型支持数据的插入和删除,还需要实现以下方法:
- insertRows(int row, int count, const QModelIndex &parent = QModelIndex())
- removeRows(int row, int count, const QModelIndex &parent = QModelIndex())
- insertColumns(int column, int count, const QModelIndex &parent = QModelIndex())
- removeColumns(int column, int count, const QModelIndex &parent = QModelIndex())
在实现这些方法时,需要调用 beginInsertRows()、endInsertRows()、beginRemoveRows()、endRemoveRows()、beginInsertColumns()、endInsertColumns()、beginRemoveColumns() 和 endRemoveColumns() 等函数,以便通知所有连接的视图关于模型的更改。
3、重要信号
QAbstractTableModel 还发出一些重要的信号,用于通知视图关于模型的更改:
- dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>() const):当模型中某个范围的数据发生更改时发出此信号。
- headerDataChanged(Qt::Orientation orientation, int first, int last):当模型的表头数据发生更改时发出此信号。
- layoutChanged():当模型的底层数据结构发生变化,导致整个布局需要重新绘制时发出此信号。
4、重要角色和标志
以下是QAbstractTableModel 类中一些常见的角色和标志及其简要介绍:
角色(Role)
- Qt::DisplayRole:用于显示的数据。
- Qt::EditRole:用于编辑的数据。
- Qt::ToolTipRole:用于显示工具提示的数据。
- Qt::DecorationRole:用于显示装饰图标的数据。
- Qt::CheckstateRole:用于显示复选框状态的数据。
标志(Flags)
- Qt::ItemIsSelectable:项是可选中的。
- Qt::ItemIsEditable:项是可编辑的。
- Qt::ItemIsEnabled:项是启用的。
- Qt::ItemIsUserCheckable:项是用户可复选的。
#include <QApplication>
#include <QMainWindow>
#include <QTableView>
#include <QVariant>
#include <QVector>class TableModel : public QAbstractTableModel
{Q_OBJECTpublic:TableModel(QObject *parent = nullptr) : QAbstractTableModel(parent){// 初始化数据dataList = {{"Alice", "30", "Engineer"},{"Bob", "25", "Designer"},{"Charlie", "35", "Manager"}};}// 获取行数int rowCount(const QModelIndex &parent = QModelIndex()) const override{if (parent.isValid()) return 0;return dataList.size();}// 获取列数int columnCount(const QModelIndex &parent = QModelIndex()) const override{if (parent.isValid()) return 0;return dataList.isEmpty() ? 0 : dataList[0].size();}// 获取数据项的值QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override{if (!index.isValid() || role != Qt::DisplayRole)return QVariant();return dataList[index.row()][index.column()];}// 标题QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override{if (role != Qt::DisplayRole)return QVariant();if (orientation == Qt::Horizontal) {switch (section) {case 0: return "Name";case 1: return "Age";case 2: return "Occupation";}}return QVariant();}// 设置数据项的值bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override{if (index.isValid() && role == Qt::EditRole) {dataList[index.row()][index.column()] = value.toString();emit dataChanged(index, index, {role});return true;}return false;}// 获取数据项的标志属性Qt::ItemFlags flags(const QModelIndex &index) const override{if (!index.isValid())return Qt::NoItemFlags;return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;}// 插入新行bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()) override{beginInsertRows(QModelIndex(), position, position + rows - 1);for (int row = 0; row < rows; ++row) {dataList.insert(position, {"", "", ""});}endInsertRows();return true;}// 移除行bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()) override{beginRemoveRows(QModelIndex(), position, position + rows - 1);for (int row = 0; row < rows; ++row) {dataList.removeAt(position);}endRemoveRows();return true;}private:QVector<QVector<QString>> dataList;
};int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建主窗口QMainWindow mainWindow;mainWindow.setWindowTitle("QAbstractTableModel Example");mainWindow.resize(400, 300);// 创建自定义表模型TableModel *model = new TableModel;// 创建表视图QTableView *tableView = new QTableView;tableView->setModel(model);tableView->horizontalHeader()->setStretchLastSection(true);tableView->setEditTriggers(QAbstractItemView::DoubleClicked);// 布局管理QVBoxLayout *layout = new QVBoxLayout;layout->addWidget(tableView);QWidget *centralWidget = new QWidget;centralWidget->setLayout(layout);mainWindow.setCentralWidget(centralWidget);// 显示主窗口mainWindow.show();return app.exec();
}


- 觉得有帮助的话,打赏一下呗。。

相关文章:
qt QAbstractTableModel详解
1、概述 QAbstractTableModel 是 Qt 框架中的一个类,用于在 Qt 应用程序中实现自定义的表格数据模型。它是 Qt 中的一个抽象基类,提供了创建和操作表格数据所需的接口。QAbstractTableModel 为模型提供了一个标准接口,这些模型将其数据表示为…...
掌握 Navicat 数据库结构设计 | 提升工作效率的秘诀
近期,我们介绍了 Navicat 17 的一系列的新特性,包括:兼容更多数据库、全新的模型设计、可视化 BI、智能数据分析、可视化查询解释、高质量数据字典、增强用户体验、扩展 MongoDB 功能、轻松固定查询结果、便捷 URI、支持更多平台等。今天&…...
Ollama AI 框架缺陷可能导致 DoS、模型盗窃和中毒
近日,东方联盟网络安全研究人员披露了 Ollama 人工智能 (AI) 框架中的六个安全漏洞,恶意行为者可能会利用这些漏洞执行各种操作,包括拒绝服务、模型中毒和模型盗窃。 知名网络安全专家、东方联盟创始人郭盛华表示:“总的来说&…...
vue 3:监听器
目录 1. 基本概念 2. 侦听数据源类型 1. 监听getter函数 2. 监听 ref 或 reactive 的引用 3. 多个来源组成的数组 4. 避免直接传递值!!! 3. 深层侦听器 4. 立即回调的侦听器 5. 一次性侦听器 6. watchEffect() 7. 暂停、恢复和停止…...
Java学习路线:Maven(四)Maven常用命令
在IDEA的Maven模块中,可以看到每个项目都有一个生命周期 这些生命周期实际上是Maven的一些插件,每个插件都有各自的功能,而双击这些插件就可以执行命令 这些命令的功能如下: clean:清除整个 target文件夹,…...
服务器数据恢复—分区结构被破坏的reiserfs文件系统数据恢复案例
服务器数据恢复环境: 一台服务器中有一组由4块SAS硬盘组建的RAID5阵列,上层安装linux操作系统统。分区结构:boot分区LVM卷swap分区(按照顺序),LVM卷中划分了一个reiserfs文件系统作为根分区。 服务器故障…...
lua入门教程:type函数
在Lua中,type 函数是一个内置函数,用于返回给定值的类型。Lua 支持多种数据类型,包括 nil(空值)、boolean(布尔值)、number(数字)、string(字符串)…...
Java图片转word
该方法可以控制一页是否只显示存放一张图片 第一步 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency><dependency><groupId>org.apache…...
立体视觉的核心技术:视差计算与图像校正详解
立体视觉的核心技术:视差计算与图像校正详解 在立体视觉中,通过双目相机(即左右两台相机)的不同视角捕获的图像,结合几何关系,我们可以推算出场景中物体的深度。本文将深入讲解如何基于视差(di…...
PaddleNLP的FAQ问答机器人
项目源码获取方式见文章末尾! 600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【DDRNet模型创新实现人像分割】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实…...
2024年12月中国多场国际学术会议,EI检索录用!
2024年12月,多场国际学术会议将在中国多地召开,涵盖AI、机器人、大数据、网络安全、传感制造、环境工程、物联网等领域,促进学术交流,录用论文将EI检索,诚邀国内外专家参会。 第三届人工智能、人机交互和机器人国际学…...
日语学习的难易程度
日语学习的难易程度是一个相对主观的问题,它受到多种因素的影响,包括个人的语言学习能力、学习方法、学习时间、学习资源的可获得性以及个人对日语文化的兴趣和投入程度等。以下是对日语学习难易程度的一些分析: 优点与易学之处 文字系统&am…...
java-web-web后端知识小结
spring框架三大核心: IOC--控制反转 DI---依赖注入 AOP--面向切面编程 web开发技术小结 1.过滤器,JWT令牌 2.三层架构 IOC, DI AOP, 全局异常处理, 事务管理 mybatis 3.数据操作与存储 mysql 阿里云OSS(云存储) 各个技术的归属: 1.过滤器, cookie,session--javaWeb 2.JWT, 阿里…...
常见的排序算法(二)
归并排序 归并排序(Merge Sort)是一种基于分治法(Divide and Conquer)的排序算法。它将一个大的问题分解成小的问题,然后递归地解决这些小问题,最后合并(merge)得到最终的排序结果。…...
spark的RDD分区的设定规则
目录 一、第一种:parallelize 获取rdd时 二、第二种:通过外部读取数据-textFile 三、上面提到了默认分区数,那么默认分区是怎么计算呢? 一、第一种:parallelize 获取rdd时 没有指定:spark.default.paral…...
【点云网络】voxelnet 和 pointpillar
VoxelNet 和 pointpillar 这两个网络可以认为后者是前者的升级版本,都是采用了空间划分的方法, 一个是体素,一个是pillar, 前者是3D卷积处理中间特征,后者是2D卷积处理中间特征。 voxelnet voxelnet 应该是比较早的onestage的网…...
HAL库硬件IIC驱动气压传感器BMP180
环境 1、keilMDK 5.38 2、STM32CUBEMX 初始配置 默认即可。 程序 1、头文件 #ifndef __BMP_180_H #define __BMP_180_H#include "main.h"typedef struct {float fTemp; /*温度,摄氏度*/float fPressure; /*压力,pa*/float fAltitude; /*…...
探索Python音频处理的奥秘:Pydub库的魔法
文章目录 探索Python音频处理的奥秘:Pydub库的魔法第一部分:背景介绍第二部分:Pydub是什么?第三部分:如何安装Pydub?第四部分:Pydub的简单函数使用方法1. 打开音频文件2. 播放音频3. 导出音频文…...
LeetCode 热题100(七)【链表】(2)
目录 7.6合并两个有序链表(简单) 7.7两数相加(中等) 7.8删除链表的倒数第N个节点(中等) 7.9两两交换链表中的节点(中等) 7.10k个一组翻转链表(困难) 7.6…...
计算机网络 TCP/IP体系 网络层
一. 网络层的基本概念 网络层主要负责将数据从源端主机发送到目的端主机。在这一过程中,网络层要解决的关键问题是数据包的路由选择,即确定数据包通过互联网的最佳路径。 1.1 网络层的信息类型 数据包:这是网络层传输的主要形式,…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
