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 网络层的信息类型 数据包:这是网络层传输的主要形式,…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
大数据驱动企业决策智能化的路径与实践
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:数据驱动的企业竞争力重构 在这个瞬息万变的商业时代,“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…...