QStandardItemModel与自定义Model
QStandardItemModel是Qt提供的开箱即用的通用模型而自定义Model则是通过继承QAbstractItemModel或其子类实现高度定制化的数据展示。下面我会从概念、使用场景、实现方式等维度详细讲解这两种模型。一、QStandardItemModel 详解1. 核心概念QStandardItemModel是Qt模型/视图框架中最常用的通用模型继承自QAbstractItemModel专为列表、表格、树形结构设计内部通过QStandardItem存储数据无需手动实现模型的虚函数开箱即用。适用场景快速实现简单的数据展示如表格、列表数据结构不复杂、无需高度定制化逻辑临时数据展示如配置项列表、简单报表2. 核心用法Qt5.91基本初始化与数据设置#includeQApplication#includeQTableView#includeQStandardItemModel#includeQStandardItemintmain(intargc,char*argv[]){QApplicationa(argc,argv);// 1. 创建模型参数(行数, 列数)QStandardItemModelmodel(3,4);// 3行4列的表格模型// 2. 设置表头model.setHorizontalHeaderLabels({姓名,年龄,性别,职业});// 3. 填充数据两种方式// 方式1通过setItem设置单元格行、列从0开始QStandardItem*item1newQStandardItem(张三);item1-setEditable(false);// 设置单元格不可编辑model.setItem(0,0,item1);model.setItem(0,1,newQStandardItem(25));model.setItem(0,2,newQStandardItem(男));model.setItem(0,3,newQStandardItem(工程师));// 方式2通过index设置数据更通用支持角色QModelIndex indexmodel.index(1,0);// 获取第2行第1列的索引model.setData(index,李四,Qt::DisplayRole);// 显示文本model.setData(index,备注测试数据,Qt::ToolTipRole);// 鼠标悬浮提示model.setData(model.index(1,1),30);model.setData(model.index(1,2),女);model.setData(model.index(1,3),设计师);// 4. 绑定到视图QTableViewQTableView view;view.setModel(model);view.resize(600,300);view.show();returna.exec();}2常用APIQt5.9关键接口接口作用setItem(int row, int col, QStandardItem* item)设置单元格数据item(int row, int col)获取单元格的QStandardItem对象setHorizontalHeaderLabels(const QStringList labels)设置水平表头appendRow(const QListQStandardItem* items)追加一行数据removeRow(int row)删除指定行clear()清空所有数据setData(const QModelIndex index, const QVariant value, int role)设置指定角色的数据如显示、提示、颜色3关键特性多角色支持除了Qt::DisplayRole显示文本还支持Qt::BackgroundRole背景色、Qt::ForegroundRole前景色、Qt::CheckStateRole复选框等。示例// 设置单元格背景色为红色model.item(0,0)-setBackground(QBrush(Qt::red));// 设置复选框选中QStandardItem*checkItemnewQStandardItem();checkItem-setCheckState(Qt::Checked);model.setItem(2,0,checkItem);自动管理内存QStandardItemModel会接管QStandardItem的内存无需手动delete除非从模型中移除。支持树形结构通过QStandardItem::appendRow(QStandardItem* child)可以构建树形结构配合QTreeView使用。二、自定义Model 详解当QStandardItemModel无法满足需求如大数据量、自定义数据结构、懒加载、复杂业务逻辑时需要继承QAbstractItemModel或其子类QAbstractTableModel/QAbstractListModel实现自定义模型。1. 核心原则Qt模型/视图框架的核心是模型提供数据索引QModelIndex视图通过索引获取数据自定义模型需实现以下核心虚函数根据场景选择虚函数作用适用场景rowCount(const QModelIndex parent)返回行数所有模型columnCount(const QModelIndex parent)返回列数表格/树形模型data(const QModelIndex index, int role)返回指定索引、指定角色的数据所有模型核心headerData(int section, Qt::Orientation orientation, int role)返回表头数据表格/列表模型index(int row, int column, const QModelIndex parent)创建模型索引所有模型parent(const QModelIndex index)返回父索引树形模型setData(const QModelIndex index, const QVariant value, int role)设置数据可编辑模型可编辑场景flags(const QModelIndex index)返回索引的标志如是否可编辑、可选所有模型2. 自定义表格模型示例Qt5.9以自定义表格模型为例继承QAbstractTableModel简化实现展示核心逻辑1自定义数据结构首先定义存储数据的结构体替代QStandardItem// UserInfo.h#includeQAbstractTableModel#includeQVariant#includevector// 自定义数据结构structUserInfo{QString name;intage;QString gender;QString job;};// 自定义表格模型classUserTableModel:publicQAbstractTableModel{Q_OBJECTpublic:// 构造函数explicitUserTableModel(QObject*parentnullptr):QAbstractTableModel(parent){}// 1. 重写返回行数introwCount(constQModelIndexparentQModelIndex())constoverride{Q_UNUSED(parent);// 表格模型parent为空returnm_userList.size();}// 2. 重写返回列数intcolumnCount(constQModelIndexparentQModelIndex())constoverride{Q_UNUSED(parent);return4;// 姓名、年龄、性别、职业}// 3. 重写核心返回指定索引的数据QVariantdata(constQModelIndexindex,introleQt::DisplayRole)constoverride{// 校验索引有效性if(!index.isValid()||index.row()m_userList.size()||index.column()4){returnQVariant();}constUserInfouserm_userList[index.row()];// 根据角色和列返回数据switch(role){caseQt::DisplayRole:// 显示文本switch(index.column()){case0:returnuser.name;case1:returnuser.age;case2:returnuser.gender;case3:returnuser.job;default:returnQVariant();}caseQt::BackgroundRole:// 背景色奇数行灰色if(index.row()%21){returnQBrush(Qt::lightGray);}break;caseQt::TextAlignmentRole:// 文本对齐年龄居中if(index.column()1){returnQt::AlignCenter;}break;default:break;}returnQVariant();}// 4. 重写表头数据QVariantheaderData(intsection,Qt::Orientation orientation,introleQt::DisplayRole)constoverride{if(role!Qt::DisplayRole){returnQVariant();}if(orientationQt::Horizontal){// 水平表头switch(section){case0:return姓名;case1:return年龄;case2:return性别;case3:return职业;default:returnQVariant();}}else{// 垂直表头行号returnsection1;}}// 5. 重写设置数据支持编辑boolsetData(constQModelIndexindex,constQVariantvalue,introleQt::EditRole)override{if(!index.isValid()||index.row()m_userList.size()||index.column()4){returnfalse;}UserInfouserm_userList[index.row()];if(roleQt::EditRole){switch(index.column()){case0:user.namevalue.toString();break;case1:user.agevalue.toInt();break;case2:user.gendervalue.toString();break;case3:user.jobvalue.toString();break;default:returnfalse;}// 通知视图数据已更新必须调用emitdataChanged(index,index);returntrue;}returnfalse;}// 6. 重写设置索引标志可编辑、可选Qt::ItemFlagsflags(constQModelIndexindex)constoverride{if(!index.isValid()){returnQt::NoItemFlags;}// 基础标志 可编辑returnQAbstractTableModel::flags(index)|Qt::ItemIsEditable;}// 自定义接口添加数据voidaddUser(constUserInfouser){// 通知视图开始插入行beginInsertRows(QModelIndex(),m_userList.size(),m_userList.size());m_userList.push_back(user);// 通知视图结束插入行必须配对调用endInsertRows();}// 自定义接口清空数据voidclearUsers(){beginResetModel();// 重置模型m_userList.clear();endResetModel();}private:std::vectorUserInfom_userList;// 存储数据的容器};2使用自定义模型// main.cpp#includeQApplication#includeQTableView#includeUserInfo.hintmain(intargc,char*argv[]){QApplicationa(argc,argv);// 1. 创建自定义模型UserTableModel model;// 2. 添加测试数据model.addUser({张三,25,男,工程师});model.addUser({李四,30,女,设计师});model.addUser({王五,28,男,产品经理});// 3. 绑定到视图QTableView view;view.setModel(model);view.resize(600,300);view.show();returna.exec();}3. 自定义Model 关键注意事项索引有效性校验data()/setData()中必须先校验index.isValid()以及行/列是否超出范围否则会导致崩溃。数据变更通知插入/删除行必须调用beginInsertRows()/endInsertRows()、beginRemoveRows()/endRemoveRows()。数据更新必须调用emit dataChanged(index, index)指定更新的索引范围。模型重置调用beginResetModel()/endResetModel()批量修改数据时使用。✅ 错误示例直接修改数据容器但不通知视图 → 视图不会刷新。性能优化大数据量时重写fetchMore()和canFetchMore()实现懒加载只加载当前视图可见的数据。避免在data()中执行复杂逻辑视图会频繁调用该函数。角色扩展可以自定义角色如enum { UserIdRole Qt::UserRole 1 }用于传递额外数据。三、QStandardItemModel vs 自定义Model维度QStandardItemModel自定义Model开发效率高开箱即用无需写虚函数低需手动实现核心虚函数灵活性低固定数据结构定制化有限高完全自定义数据结构和逻辑性能中等大数据量可能卡顿高可针对性优化如懒加载内存占用较高每个单元格一个QStandardItem较低自定义紧凑数据结构适用场景简单表格/列表、临时数据展示大数据量、复杂业务逻辑、懒加载、自定义数据结构总结QStandardItemModel是Qt5.9中快速实现数据展示的首选无需手动实现模型虚函数通过QStandardItem管理数据适合简单的表格/列表场景支持多角色数据和树形结构。自定义Model需继承QAbstractTableModel/QAbstractItemModel实现核心虚函数rowCount()/columnCount()/data()等必须通过beginInsertRows()/dataChanged()等接口通知视图数据变更适合大数据量、高定制化的场景。选择原则简单场景用QStandardItemModel提升开发效率复杂场景用自定义Model保证性能和灵活性。

相关新闻

从流量被动到AI引荐主动:2026年GEO实战架构与顶级优化

从流量被动到AI引荐主动:2026年GEO实战架构与顶级优化

【前言】:进入2026年,传统的“蓝链”搜索正在迅速瓦解。根据Semrush最新发布的《2026 AI搜索趋势报告》,超过45%的商业查询已由AI Overviews(AIO)和对话式引擎直接给出答案。品牌面临的现状极其严酷:要么成…

2026/5/17 12:57:12 阅读更多 →
2026年四川正规GEO优化公司TOP排名出炉,哪家能拔得头筹?

2026年四川正规GEO优化公司TOP排名出炉,哪家能拔得头筹?

家人们,最近2026年四川正规GEO优化公司TOP排名新鲜出炉啦。在当今这个AI搜索重塑流量格局的时代,GEO优化服务可是能帮助品牌抢占AI流量红利的关键,所以这个排名一出来就备受关注。今天咱就来唠唠这里面的门道,看看哪家公司能在这场…

2026/7/4 21:33:25 阅读更多 →
@ContentFontStyle注解颜色说明

@ContentFontStyle注解颜色说明

ContentFontStyle 是 EasyExcel 框架的注解,color 字段对应 Apache POI 的 IndexedColors 颜色索引值。 …

2026/7/5 5:55:20 阅读更多 →

最新新闻

基于A89307和PIC18F4620的BLDC电机FOC控制方案

基于A89307和PIC18F4620的BLDC电机FOC控制方案

1. 项目背景与核心需求在工业自动化、无人机和电动汽车等领域,无刷直流电机(BLDC)因其高效率、高功率密度和长寿命等优势,正逐步取代传统有刷电机。然而,要实现BLDC的高性能控制并非易事——这需要精确的磁场定向控制&…

2026/7/5 7:50:14 阅读更多 →
GLM-5.2 火了以后,Cursor、Claude Code、Codex 怎么统一配置 API?

GLM-5.2 火了以后,Cursor、Claude Code、Codex 怎么统一配置 API?

GLM-5.2 火了以后,Cursor、Claude Code、Codex 该怎么统一配置 API? 最近一段时间,很多人开始把注意力放到 GLM-5.2、DeepSeek、Kimi、豆包、Claude、Gemini 这类模型的实际接入上。 但真正开始配置以后,会发现问题并不只是“哪个…

2026/7/5 7:50:14 阅读更多 →
Nginx配置防御PDF文件XSS攻击:安全响应头实战指南

Nginx配置防御PDF文件XSS攻击:安全响应头实战指南

1. 项目概述:PDF里的XSS,一个被忽视的Web安全盲区 很多Web开发者,包括我自己在早期,都曾有过一个天真的想法:用户上传的PDF文件是“安全”的。毕竟,它不像HTML或JavaScript文件那样能被浏览器直接解析执行…

2026/7/5 7:48:14 阅读更多 →
WSEN-ISDS三轴MEMS传感器与PIC18F47K42的6DOF运动跟踪方案

WSEN-ISDS三轴MEMS传感器与PIC18F47K42的6DOF运动跟踪方案

1. 项目背景与硬件选型解析在机器人导航、工业自动化控制、无人机飞控等需要精确空间定位的领域,三轴运动跟踪一直是核心挑战。传统方案往往需要分别使用加速度计和陀螺仪,再通过复杂的传感器融合算法计算姿态,不仅增加了系统复杂度&#xff…

2026/7/5 7:48:14 阅读更多 →
OpenAI-compatible API 网关实践:Claude API、GPT、Gemini 重试与备用模型切换

OpenAI-compatible API 网关实践:Claude API、GPT、Gemini 重试与备用模型切换

# OpenAI-compatible API 网关实践:Claude/GPT/Gemini 的重试和备用模型切换在真实业务里接入 Claude API、GPT 或 Gemini,最容易低估的不是单次请求怎么写,而是失败时系统会不会稳住。小团队如果只有一个模型、一个 key、一个固定 endpoint&…

2026/7/5 7:46:13 阅读更多 →
BetterJoy终极指南:让Switch手柄在PC上完美工作的5个关键步骤

BetterJoy终极指南:让Switch手柄在PC上完美工作的5个关键步骤

BetterJoy终极指南:让Switch手柄在PC上完美工作的5个关键步骤 【免费下载链接】BetterJoy Allows the Nintendo Switch Pro Controller, Joycons and SNES controller to be used with CEMU, Citra, Dolphin, Yuzu and as generic XInput 项目地址: https://gitco…

2026/7/5 7:46:13 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻