QT M/V架构开发实战:QStandardItemModel介绍

### 目录

  • [@[TOC](目录)](#目录 @TOC 前言 一、QStandardItemModel初步介绍 二、基本功能 1.创建 2.基本属性与方法 三、何时使用 QStandardItemModel? 四、何时避免使用 QStandardItemModel?)
  • [前言](#目录 @TOC 前言 一、QStandardItemModel初步介绍 二、基本功能 1.创建 2.基本属性与方法 三、何时使用 QStandardItemModel? 四、何时避免使用 QStandardItemModel?)
  • [一、QStandardItemModel初步介绍](#目录 @TOC 前言 一、QStandardItemModel初步介绍 二、基本功能 1.创建 2.基本属性与方法 三、何时使用 QStandardItemModel? 四、何时避免使用 QStandardItemModel?)
  • [二、基本功能](#目录 @TOC 前言 一、QStandardItemModel初步介绍 二、基本功能 1.创建 2.基本属性与方法 三、何时使用 QStandardItemModel? 四、何时避免使用 QStandardItemModel?)
  • [1.创建](#目录 @TOC 前言 一、QStandardItemModel初步介绍 二、基本功能 1.创建 2.基本属性与方法 三、何时使用 QStandardItemModel? 四、何时避免使用 QStandardItemModel?)
  • [2.基本属性与方法](#目录 @TOC 前言 一、QStandardItemModel初步介绍 二、基本功能 1.创建 2.基本属性与方法 三、何时使用 QStandardItemModel? 四、何时避免使用 QStandardItemModel?)
  • [三、​何时使用 QStandardItemModel?​​](#目录 @TOC 前言 一、QStandardItemModel初步介绍 二、基本功能 1.创建 2.基本属性与方法 三、何时使用 QStandardItemModel? 四、何时避免使用 QStandardItemModel?)
  • [四、何时避免使用 QStandardItemModel?​​](#目录 @TOC 前言 一、QStandardItemModel初步介绍 二、基本功能 1.创建 2.基本属性与方法 三、何时使用 QStandardItemModel? 四、何时避免使用 QStandardItemModel?)

前言


本文主要介绍的是使用代码生成的情况下对控件的介绍,包括拥有的功能及能修改的样式,也会说明在qtdesiner拖拽控件生成和使用代码生成控件的区别(如果有的话,遇到了的会说),此版本不属于最终版本,以后遇到什么新奇的点会继续更新!本文基于QT官方的文档进行的编写,QT版本为qt 5.14.0,编写环境为Windows11。不得不说官方文档真是个好东西,有时候有些不会的上去一看就能有灵感解决了,可惜没有中文版本的。

一、QStandardItemModel初步介绍

QStandardItemModel 是 QAbstractItemModel的一个具体实现。它的核心思想是使用 QStandardItem对象来存储和管理数据。每个 QStandardItem代表模型中的一个数据项(单元格),它可以存储数据(通过角色)、设置标志(可编辑、可选等)、拥有子项(构建树结构)等。

​核心优势 :​​
1.​​简单易用 :​​ 相比直接继承 QAbstractItemModel并实现所有纯虚函数,使用 QStandardItemModel要简单得多。你只需要创建 QStandardItem对象并填充到模型中即可。
2.​​内置功能 :​​ 它自动处理了数据变化通知(dataChanged信号)、结构变化通知(行/列插入删除的信号)等繁琐工作。你修改 QStandardItem的属性,模型会自动发出相应信号通知视图更新。
3.​​灵活性 :​​ 非常适合表示表格数据(二维)和树状数据(层次结构)。
​​4.集成 QStandardItem:​​ QStandardItem本身功能强大,可以存储多种类型的数据(文本、图标、颜色、字体等),设置各种属性(对齐、背景、前景、勾选状态等)。

二、基本功能

1.创建

cpp 复制代码
// 创建一个空模型,可以稍后设置行列
QStandardItemModel *model = new QStandardItemModel(parent);
// 创建时指定初始行数和列数
QStandardItemModel *model = new QStandardItemModel(rows, columns, parent);

2.基本属性与方法

1)​设置表头

cpp 复制代码
// 设置水平表头标签 (列名)
model->setHorizontalHeaderLabels(QStringList() << "Name" << "Age" << "Department");
// 设置垂直表头标签 (行名,较少用)
model->setVerticalHeaderLabels(QStringList() << "Row 1" << "Row 2");
// 获取水平表头项 (QStandardItem*),可以进一步设置其属性(字体、颜色等)
QStandardItem *headerItem = model->horizontalHeaderItem(column);
headerItem->setTextAlignment(Qt::AlignCenter);
headerItem->setBackground(QBrush(Qt::lightGray));

2)创建数据项()

cpp 复制代码
// 创建一个包含文本的项
QStandardItem *itemName = new QStandardItem("Alice");
// 创建一个包含文本和图标的项
QStandardItem *itemWithIcon = new QStandardItem(QIcon(":/images/user.png"), "Bob");
// 创建一个可勾选的项
QStandardItem *checkableItem = new QStandardItem("Task Complete");
checkableItem->setCheckable(true);
checkableItem->setCheckState(Qt::Checked); // 或 Qt::Unchecked

3)设置项到模型

cpp 复制代码
// 设置单个项到指定位置 (行, 列)
model->setItem(row, column, item);
// 设置整行数据 (一个 QStandardItem 列表代表一行中的各列)
QList<QStandardItem*> rowItems;
rowItems << new QStandardItem("Alice") << new QStandardItem("28") << new QStandardItem("Engineering");
model->appendRow(rowItems); // 添加到末尾
model->insertRow(row, rowItems); // 插入到指定行
// 设置整列数据 (较少用)
QList<QStandardItem*> columnItems;
// ... 填充列数据 ...
model->appendColumn(columnItems);
model->insertColumn(column, columnItems);

4)​获取项

cpp 复制代码
// 获取指定位置的项 (行, 列)
QStandardItem *item = model->item(row, column);
// 获取水平表头项 (列)
QStandardItem *headerItem = model->horizontalHeaderItem(column);
// 获取垂直表头项 (行)
QStandardItem *vHeaderItem = model->verticalHeaderItem(row);

5)操作行和列

cpp 复制代码
// 插入行
model->insertRow(row); // 插入空行
model->insertRow(row, listOfItems); // 插入带数据的行

// 插入列
model->insertColumn(column); // 插入空列
model->insertColumn(column, listOfItems); // 插入带数据的列 (每项代表该列的一行)

// 追加行/列
model->appendRow(listOfItems);
model->appendColumn(listOfItems);

// 删除行/列
model->removeRow(row);
model->removeRows(row, count); // 删除从 row 开始的 count 行
model->removeColumn(column);
model->removeColumns(column, count); // 删除从 column 开始的 count 列

// 获取行/列数
int rows = model->rowCount();
int cols = model->columnCount();
int colsForRow = model->rowCount(parentIndex); // 对于树状结构,获取父节点下的行数

6)构建树状结构 (层次数据)

cpp 复制代码
// 创建父项
QStandardItem *parentItem = model->invisibleRootItem(); // 获取模型的根项 (不可见)
// 或者创建一个顶级项
QStandardItem *topLevelItem = new QStandardItem("Departments");

// 创建子项
QStandardItem *childItem1 = new QStandardItem("Engineering");
QStandardItem *childItem2 = new QStandardItem("Marketing");

// 将子项添加到父项下 (作为一行)
parentItem->appendRow(childItem1);
parentItem->appendRow(childItem2);
// 或者 topLevelItem->appendRow(childItem1);

// 也可以添加一整行子项到父项下
QList<QStandardItem*> childRow;
childRow << new QStandardItem("Alice") << new QStandardItem("Developer");
parentItem->appendRow(childRow); // parentItem 下新增一行,包含两列

// 获取父项的子项
QStandardItem *firstChild = parentItem->child(row, column); // 获取指定位置的子项
int childCount = parentItem->rowCount(); // 获取子项行数 (直接子节点数)

// 获取项的父项
QStandardItem *parentOfChild = childItem1->parent();

7)访问和修改项数据 (QStandardItem的接口)

cpp 复制代码
// 设置/获取文本 (DisplayRole)
item->setText("New Name");
QString name = item->text();

// 设置/获取图标 (DecorationRole)
item->setIcon(QIcon(":/images/icon.png"));
QIcon icon = item->icon();

// 设置/获取字体 (FontRole)
QFont boldFont;
boldFont.setBold(true);
item->setFont(boldFont);
QFont usedFont = item->font();

// 设置/获取文本对齐 (TextAlignmentRole)
item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
Qt::Alignment align = item->textAlignment();

// 设置/获取背景色 (BackgroundRole)
item->setBackground(QBrush(Qt::yellow));
QBrush bgBrush = item->background();

// 设置/获取前景色 (文本颜色, ForegroundRole)
item->setForeground(QBrush(Qt::red));
QBrush fgBrush = item->foreground();

// 设置/获取勾选状态和是否可勾选 (CheckStateRole, ItemIsUserCheckable flag)
item->setCheckable(true);
item->setCheckState(Qt::Checked); // Qt::Unchecked, Qt::PartiallyChecked
bool isChecked = (item->checkState() == Qt::Checked);
bool isCheckable = item->isCheckable();

// 设置/获取是否可编辑 (ItemIsEditable flag)
item->setEditable(false);
bool editable = item->isEditable();

// 设置/获取是否启用 (ItemIsEnabled flag)
item->setEnabled(false);
bool enabled = item->isEnabled();

// 设置/获取是否可选 (ItemIsSelectable flag)
item->setSelectable(false); // 注意:通常通过 flags() 设置,但 QStandardItem 提供了这个便捷方法
bool selectable = item->isSelectable();

// 设置/获取工具提示 (ToolTipRole)
item->setToolTip("This is an important item");
QString tip = item->toolTip();

// 设置/获取状态提示 (StatusTipRole)
item->setStatusTip("Shows in status bar");
QString statusTip = item->statusTip();

// 设置/获取自定义数据 (使用 Qt::UserRole 或更高)
item->setData(QVariant(42), Qt::UserRole); // 存储一个整数
item->setData(QVariant("Custom Info"), Qt::UserRole + 1); // 存储一个字符串
int customInt = item->data(Qt::UserRole).toInt();
QString customStr = item->data(Qt::UserRole + 1).toString();

// 获取项的标志 (flags)
Qt::ItemFlags flags = item->flags();

8)查找项

cpp 复制代码
// 通过文本查找项 (精确匹配,遍历所有项)
QList<QStandardItem*> foundItems = model->findItems("Alice", Qt::MatchExactly);

// 通过文本查找项 (匹配开头、包含、正则等,Qt::MatchFlag)
QList<QStandardItem*> foundStartsWith = model->findItems("A", Qt::MatchStartsWith);

// 查找指定项所在的行和列 (需要知道父项)
QStandardItem *parentItem = ...; // 父项 (或 invisibleRootItem())
int row = item->row();
int column = item->column();

9)排序

cpp 复制代码
// 启用视图排序 (最简单)
tableView->setSortingEnabled(true); // 用户点击表头即可排序

// 在代码中排序 (基于列)
model->sort(column, Qt::AscendingOrder); // 升序
model->sort(column, Qt::DescendingOrder); // 降序

// 自定义排序规则 (需要继承 QStandardItemModel 并重写 lessThan)
class MySortModel : public QStandardItemModel {
protected:
    bool lessThan(const QModelIndex &left, const QModelIndex &right) const override {
        // 获取数据进行比较,left 和 right 是同一列的不同行索引
        QVariant leftData = data(left);
        QVariant rightData = data(right);
        // ... 实现你的比较逻辑 ...
        return myCustomComparisonResult;
    }
};

10)与视图连接

cpp 复制代码
QTableView *tableView = new QTableView;
tableView->setModel(model); // 关键一步!

QTreeView *treeView = new QTreeView;
treeView->setModel(model); // 如果 model 是树状结构

三、​何时使用 QStandardItemModel?​​

数据量不大:​​ 内存中可以容纳所有 QStandardItem对象。

​​数据结构相对简单:​​ 表格或树状结构。

​​需要快速开发:​​ 不想花费精力实现完整的 QAbstractItemModel。

​​需要灵活设置单元格属性:​​ QStandardItem提供了丰富的属性设置接口。

四、何时避免使用 QStandardItemModel?​​

​数据量巨大 (百万级):​​ 创建和管理大量 QStandardItem对象会消耗大量内存和 CPU,性能会成为瓶颈。此时应使用自定义的 QAbstractItemModel(如基于 QAbstractTableModel),实现按需提供数据的 data()函数。

​​数据源特殊:​​ 数据来自数据库、网络或其他复杂来源,直接映射到 QStandardItem不方便或不高效。

​​需要极致的性能优化。​​

本次分享就到这里了,如果有什么错误的话请指正,或者有什么疑问的,也可以在评论区一起探讨!

相关推荐
人工干智能41 分钟前
科普:Python 中,字典的“动态创建键”特性
开发语言·python
初听于你2 小时前
缓存技术揭秘
java·运维·服务器·开发语言·spring·缓存
长路归期无望4 小时前
C语言小白实现多功能计算器的艰难历程
c语言·开发语言·数据结构·笔记·学习·算法
恒悦sunsite4 小时前
Ubuntu之apt安装ClickHouse数据库
数据库·clickhouse·ubuntu·列式存储·8123
是大强4 小时前
stm32摇杆adc数据分析
开发语言
奥尔特星云大使4 小时前
MySQL 慢查询日志slow query log
android·数据库·mysql·adb·慢日志·slow query log
来自宇宙的曹先生4 小时前
MySQL 存储引擎 API
数据库·mysql
间彧5 小时前
MySQL Performance Schema详解与实战应用
数据库
间彧5 小时前
MySQL Exporter采集的关键指标有哪些,如何解读这些指标?
数据库
weixin_446260855 小时前
Django - 让开发变得简单高效的Web框架
前端·数据库·django