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 网络层的信息类型 数据包:这是网络层传输的主要形式,…...
Agent+用药提醒:真正难的不是提醒,而是结合病情和依从性管理
用药提醒如果只做成定时推送,本质上接近一个带药品名称的闹钟。医疗健康应用里更棘手的问题是:用户是否按计划执行、漏服后如何记录、连续异常时是否需要升级提醒,以及这些规则如何被机构确认并可审计。本文只讨论技术架构和工程流程示例&…...
保姆级教程:在Ubuntu 22.04上搞定DCU-Z100(ZiFang)驱动安装与验证
保姆级教程:在Ubuntu 22.04上搞定DCU-Z100(ZiFang)驱动安装与验证 国产DCU(Deep Computing Unit)正逐渐成为高性能计算领域的新选择,而DCU-Z100(代号ZiFang)作为其中的代表产品&…...
告别通用OCR:如何用PaddleOCR针对银行卡场景做定制化检测模型优化?
告别通用OCR:如何用PaddleOCR针对银行卡场景做定制化检测模型优化? 银行卡识别一直是金融科技领域的高频需求,但通用OCR模型在应对银行卡这类特殊场景时往往力不从心。我曾参与过多个银行的移动端项目,亲眼见证过通用模型在识别卡…...
别再纠结选哪种了!一文讲透无人机测深三剑客(激光雷达/测深仪/GPR)的实战选型指南
无人机测深技术三剑客:激光雷达、测深仪与探地雷达的深度选型指南 当无人机遇上水深测量,技术选型往往成为项目成败的关键。在河道整治、水库清淤、海岸线测绘等场景中,工程师们常面临一个核心难题:如何在激光雷达、测深仪和探地雷…...
【量化】IPTQ-ViT: Post-Training Quantization of Non-linear Functions for Integer-only Vision Transformer
【PTQ】PTQViT/IPTQ-ViT (arXiv 2022) 问题: ViT 中的非线性函数(GELU、Softmax)在纯整数推理中存在计算障碍。 核心创新: 模块方法作用多项式近似 GELU用低阶多项式逼近 GELU将非线性运算转化为整数可执行的乘加Bit-shifting Softmax用位移操作近似 …...
嵌入式操作系统选型实战指南:从硬件约束到商业考量的五维决策框架
1. 项目概述:一个困扰无数工程师的经典难题干了十几年嵌入式,从8位单片机玩到多核ARM,从裸机撸到各种RTOS,再到Linux、Android,最常被问到也最头疼的问题之一就是:“老大,新项目用哪个操作系统好…...
银河麒麟系统下Qt5.9.9编译fcitx-qt5的版本适配与源码修改实战
1. 银河麒麟系统下Qt中文输入问题的根源 在银河麒麟系统上开发Qt应用程序时,中文输入法无法正常切换是个常见痛点。这个问题本质上源于Qt输入法插件与Qt版本之间的兼容性断裂。我曾在多个项目中遇到这种情况:明明系统自带输入法可以正常工作,…...
接口自动化测试框架搭建:基于Python+Requests+Pytest的实战教程
在软件测试领域,接口自动化测试是保障系统稳定性、提升测试效率的关键手段。随着敏捷开发和DevOps理念的普及,自动化测试的重要性愈发凸显。Python凭借其简洁的语法、丰富的库生态,成为接口自动化测试的首选语言;Requests库让HTTP…...
Perplexity法律文献搜索实战指南:7步构建精准检索式,避开90%的无效结果
更多请点击: https://codechina.net 第一章:Perplexity法律文献搜索实战指南:7步构建精准检索式,避开90%的无效结果 Perplexity 作为面向专业研究者的AI搜索工具,在法律文献检索中展现出远超通用搜索引擎的语义理解与…...
VS Code 迎来史诗级更新:全新 Agents 窗口发布
VS Code 在前几年古法编程时代,那就是 IDE 的王者。随着 AI Coding 的不断进步。虽然 VS Code 依托 github copilot 早早的就集成了 AI Coding 的能力。但是由于 VSCode 本身是一个 IDE ,它的核心能力还是文本编辑器。但是在 Claude, xcode 等…...
