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保证性能和灵活性。