主页 > IT业界  > 

QT基础十二、标准项模型:QStandardItemModel

QT基础十二、标准项模型:QStandardItemModel

目录

一、简介

二、核心功能

三、准备材料

1、所需要的action

 2、将action添加进菜单栏里

 3、最终样式​编辑

 4、准备数据文件

四、项目代码

1、需要用到的头文件与变量

2、初始化组件

3、打开txt文件,并导入其中数据

4、初始化standModel的数据

 5、在尾部添加一行数据

6、插入一行数据

7、删除一行数据

8、预览模式,可以查看将要保存的状态

9、保存文件

 10、将表格内的内容居中

11、 将表格内的内容居左

12、 将表格内的内容居右

13、设置字体

 14、当选择的标签变化时,更新字体种类

 15、运行结果

五、常用接口

QStandardItemModel

1、设置行列数 :

2、插入项:

3、获取项:

4、清除模型:

QStandardItem

1、设置文本:

2、设置图标:

3、设置子项 :

4、设置用户数据:


一、简介

在 Qt 框架中,标准项模型(Standard Item Model) 是一种通用的数据模型,用于表示树形或列表结构的数据。它是 QStandardItemModel 类的实现,属于 Qt 的模型-视图架构的一部分。标准项模型提供了一种简单而灵活的方式来存储和操作数据,并与视图组件(如 QTreeView、QListView 或 QTableView)结合使用。


二、核心功能

模型-视图架构 :

Qt 的模型-视图架构将数据(模型)与用户界面(视图)分离。模型负责管理数据,视图负责显示数据,两者通过信号槽机制进行交互。QStandardItemModel 是一个实现了 QAbstractItemModel 接口的具体模型类。

标准项模型的特点 :

它是一个通用的、可扩展的数据模型,支持树形结构和表格结构。数据项由 QStandardItem 对象表示,每个项可以包含文本、图标、工具提示等信息。支持动态添加、删除和修改数据项。

适用场景 :

需要快速构建简单的树形或表格视图。数据量较小且不需要复杂的自定义逻辑。适合原型开发或小型项目。
三、准备材料

注:QT的学习需要许多图片资源,如果你们缺少图片资源,建议去爱给网下载,或者让AI生成

 准备如上图片,有的是我从网上找的,有的是我用ai生成的

1、所需要的action

 2、将action添加进菜单栏里

 3、最终样式  4、准备数据文件

一个txt文件,我这里用的是我大一的C语言作业的文件,随便弄一些数据就行


四、项目代码 1、需要用到的头文件与变量 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStandardItemModel> #include <QItemSelectionModel> #include <QFileDialog> #include <QTextStream> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_actionOpen_triggered(); void on_actionAdd_triggered(); void on_actionInsert_triggered(); void on_actionDel_triggered(); void on_actionSee_triggered(); void on_actionSave_triggered(); void on_actionCenter_triggered(); void on_actionLeft_triggered(); void on_actionRight_triggered(); void on_actionBold_triggered(bool checked); void onSelectModelCurrentChanged(const QModelIndex &current, const QModelIndex &previous); void on_actionItalic_triggered(bool checked); void on_actionUnderLine_triggered(bool checked); private: void initUI(); void initModel(QStringList lineList); private: Ui::MainWindow *ui; QStandardItemModel* standModel; QItemSelectionModel* selectModel; }; #endif // MAINWINDOW_H 2、初始化组件 void MainWindow::initUI() { // 创建一个标准项模型(QStandardItemModel),并指定父对象为当前窗口(this) // 初始行列数设置为 0,表示模型为空 standModel = new QStandardItemModel(0, 0, this); // 创建一个选择模型(QItemSelectionModel),并将其与标准项模型关联 // 选择模型用于管理用户在视图中的选择状态 selectModel = new QItemSelectionModel(standModel); // 将标准项模型设置为 tableView 的数据模型 // 这样 tableView 就可以显示和操作标准项模型中的数据 ui->tableView->setModel(standModel); // 将选择模型设置为 tableView 的选择模型 // 这样 tableView 的选择操作(如点击、拖拽)会被记录到选择模型中 ui->tableView->setSelectionModel(selectModel); // 设置 tableView 的选择模式为“扩展选择”(ExtendedSelection) // 扩展选择允许用户通过按住 Ctrl 或 Shift 键进行多选 ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection); //当选定的item改变时,触发槽函数 connect(selectModel, SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(onSelectModelCurrentChanged(const QModelIndex &, const QModelIndex &))); } 3、打开txt文件,并导入其中数据 void MainWindow::on_actionOpen_triggered() { // 打开一个文件选择对话框,允许用户选择一个文件 QString fileName = QFileDialog::getOpenFileName( this, // 父窗口指针,指定对话框的父窗口 "打开一个文件", // 对话框标题,提示用户操作的目的 QCoreApplication::applicationDirPath(), // 默认打开的目录路径,这里是程序所在目录 "文本数据文件(*.txt);;所有文件(*.*)"); // 文件过滤器,限制或分类显示的文件类型 // 如果用户取消了文件选择(返回空字符串),直接退出函数 if (fileName.isEmpty()) { return; } //清除掉上一个文件的残余 standModel->clear(); ui->plainTextEdit->clear(); // 创建 QFile 对象以操作选中的文件 QFile file(fileName); // 尝试以只读和文本模式打开文件 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { // 如果文件无法打开(如权限不足或文件不存在),直接退出函数 return; } // 创建 QTextStream 对象,用于从文件中读取文本内容 QTextStream stream(&file); // 定义一个字符串列表,用于存储文件的每一行内容 QStringList lineList; // 循环读取文件的每一行内容 while (!stream.atEnd()) { // 注意:原代码中的条件 `stream.atEnd()` 是错误的,应改为 `!stream.atEnd()` QString line = stream.readLine(); // 读取一行文本 lineList.append(line); // 将读取的行添加到字符串列表中 ui->plainTextEdit->appendPlainText(line); // 将读取的行追加到 plainTextEdit 中显示 } // 关闭文件 file.close(); // 调用 initModel 函数,将读取的文件内容传递给模型进行初始化 initModel(lineList); } 4、初始化standModel的数据 void MainWindow::initModel(QStringList lineList) { // 获取文件的第一行作为表头 QString headLine = lineList[0]; // 使用正则表达式分割字符串,提取表头字段 // QRegExp("\\s+") 匹配一个或多个空白字符(包括空格、制表符等) // QString::SkipEmptyParts 忽略分割后产生的空字符串 QStringList tableHead = headLine.split(QRegExp("\\s+"), QString::SkipEmptyParts); // 将分割后的表头字段设置为标准项模型的水平表头标签 standModel->setHorizontalHeaderLabels(tableHead); // 遍历文件内容的其余行(从第二行开始) for (int i = 1; i < lineList.count(); i++) { // 对每一行使用正则表达式分割字符串,提取数据字段 auto itemStrList = lineList[i].split(QRegExp("\\s+"), QString::SkipEmptyParts); // 获取当前行的数据字段数量 int cols = itemStrList.count(); // 创建一个 QList 存储当前行的 QStandardItem 对象 QList<QStandardItem*> items; // 遍历当前行的前 (cols - 1) 个字段,创建对应的 QStandardItem 并添加到列表中 for (int j = 0; j < cols - 1; j++) { QStandardItem* item = new QStandardItem(itemStrList[j]); items.append(item); } // 创建一个特殊的 QStandardItem,用于表示“是否毕业”字段 QStandardItem* item = new QStandardItem("是否毕业"); // 设置该字段为可勾选状态 item->setCheckable(true); // 根据最后一列的值("是" 或 "否")设置复选框的状态 itemStrList[cols - 1] == "是" ? item->setCheckState(Qt::Checked) : item->setCheckState(Qt::Unchecked); // 将“是否毕业”字段添加到当前行的项列表中 items.append(item); // 将当前行的所有项添加到标准项模型中 standModel->appendRow(items); } }  5、在尾部添加一行数据 void MainWindow::on_actionAdd_triggered() { // 创建一个 QList 存储新行的所有 QStandardItem 对象 QList<QStandardItem*> items; // 遍历模型的列数(除最后一列外),为每列创建一个默认值为“未初始化”的项 for (int i = 0; i < standModel->columnCount() - 1; i++) { QStandardItem* item = new QStandardItem("未初始化"); items.append(item); } // 创建最后一列的项,表示“是否毕业”,并设置为可勾选状态,默认未勾选 QStandardItem* item = new QStandardItem("是否毕业"); item->setCheckable(true); // 设置为可勾选 item->setCheckState(Qt::Unchecked); // 默认未勾选 // 将最后一列的项添加到列表中 items.append(item); // 将新行的所有项添加到标准项模型的末尾 standModel->appendRow(items); // 清除当前的选择状态 selectModel->clearSelection(); // 获取新添加行的第一列索引,并将其设置为当前选择 auto index = standModel->index(standModel->rowCount() - 1, 0); selectModel->setCurrentIndex(index, QItemSelectionModel::Select); } 6、插入一行数据 void MainWindow::on_actionInsert_triggered() { // 创建一个 QList 存储插入行的所有 QStandardItem 对象 QList<QStandardItem*> items; // 遍历模型的列数(除最后一列外),为每列创建一个默认值为“未初始化”的项 for (int i = 0; i < standModel->columnCount() - 1; i++) { QStandardItem* item = new QStandardItem("未初始化"); items.append(item); } // 创建最后一列的项,表示“是否毕业”,并设置为可勾选状态,默认未勾选 QStandardItem* item = new QStandardItem("是否毕业"); item->setCheckable(true); // 设置为可勾选 item->setCheckState(Qt::Unchecked); // 默认未勾选 // 将最后一列的项添加到列表中 items.append(item); // 获取当前选中的索引 auto index = selectModel->currentIndex(); // 在当前选中行的位置插入新行 standModel->insertRow(index.row(), items); // 清除当前的选择状态 selectModel->clearSelection(); // 将插入行设置为当前选择 selectModel->setCurrentIndex(index, QItemSelectionModel::Select); } 7、删除一行数据 void MainWindow::on_actionDel_triggered() { // 获取当前选中的索引 auto index = selectModel->currentIndex(); // 如果当前选中的是最后一行,则直接删除该行 if (index.row() == standModel->rowCount() - 1) { standModel->removeRow(index.row()); } else { // 如果不是最后一行,则删除当前行,并保持选择状态不变 standModel->removeRow(index.row()); selectModel->setCurrentIndex(index, QItemSelectionModel::Select); } } 8、预览模式,可以查看将要保存的状态 void MainWindow::on_actionSee_triggered() { // 清空 plainTextEdit 控件中的内容,以便显示新的数据 ui->plainTextEdit->clear(); // 获取 standModel 模型中的行数和列数 int row = standModel->rowCount(); // 获取模型的总行数 int col = standModel->columnCount(); // 获取模型的总列数 QString str; // 遍历模型的所有列,获取表头的内容 for(int i = 0; i < col; i++) { // 获取第 i 列的表头项 auto item = standModel->horizontalHeaderItem(i); // 将表头项的文本添加到字符串中,并用制表符(\t)分隔 str += item->text() + "\t"; } // 将表头信息追加到 plainTextEdit 控件中 ui->plainTextEdit->appendPlainText(str); // 遍历模型的所有行(从第 1 行开始,跳过表头) for(int i = 1; i < row; i++) { // 初始化一个空字符串,用于存储当前行的数据 str = ""; // 遍历当前行的所有列(除最后一列外) for(int j = 0; j < col - 1; j++) { // 获取第 i 行、第 j 列的单元格数据 auto item = standModel->item(i, j); // 将单元格的文本添加到字符串中,并用制表符(\t)分隔 str += item->text() + "\t"; } // 处理最后一列的数据(假设最后一列是复选框) if(standModel->item(i, col - 1)->checkState() == Qt::Checked) { // 如果复选框被选中,则在字符串中添加 "是" str += "是\t"; } else { // 如果复选框未被选中,则在字符串中添加 "否" str += "否\t"; } // 将当前行的数据追加到 plainTextEdit 控件中 ui->plainTextEdit->appendPlainText(str); } } 9、保存文件

 

void MainWindow::on_actionSave_triggered() { //选择保存文件的完整路径 QString fileName = QFileDialog::getSaveFileName(this, "保存文件", QCoreApplication::applicationDirPath(), "文本数据文件(*.txt);;所有文件(*.*)"); QFile file(fileName); if(!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) { return; } QTextStream stream(&file); QString str; // 获取 standModel 模型中的行数和列数 int row = standModel->rowCount(); // 获取模型的总行数 int col = standModel->columnCount(); // 获取模型的总列数 // 遍历模型的所有列,获取表头的内容 for(int i = 0; i < col; i++) { // 获取第 i 列的表头项 auto item = standModel->horizontalHeaderItem(i); // 将表头项的文本添加到字符串中,并用制表符(\t)分隔 str += item->text() + "\t\t"; } stream << str << "\n"; // 遍历模型的所有行(从第 1 行开始,跳过表头) for(int i = 1; i < row; i++) { // 初始化一个空字符串,用于存储当前行的数据 str = ""; // 遍历当前行的所有列(除最后一列外) for(int j = 0; j < col - 1; j++) { // 获取第 i 行、第 j 列的单元格数据 auto item = standModel->item(i, j); // 将单元格的文本添加到字符串中,并用制表符(\t)分隔 str += item->text() + "\t\t"; } // 处理最后一列的数据(假设最后一列是复选框) if(standModel->item(i, col - 1)->checkState() == Qt::Checked) { // 如果复选框被选中,则在字符串中添加 "是" str += "是\t"; } else { // 如果复选框未被选中,则在字符串中添加 "否" str += "否\t"; } stream << str << "\n"; } file.close(); }  10、将表格内的内容居中 // 当用户触发“居中对齐”操作时调用此函数 void MainWindow::on_actionCenter_triggered() { // 检查是否有选中的项,如果没有选中任何项,则直接返回,不做任何操作 if (!selectModel->hasSelection()) { return; } // 获取当前选中的所有索引(即用户在界面中选中的单元格) auto indexList = selectModel->selectedIndexes(); // 遍历选中的索引列表 for (auto& index : indexList) { // 根据索引从标准模型中获取对应的项(QStandardItem) auto* item = standModel->itemFromIndex(index); // 设置该项的文本对齐方式为居中对齐 item->setTextAlignment(Qt::AlignCenter); } } 11、 将表格内的内容居左 // 当用户触发“左对齐”操作时调用此函数 void MainWindow::on_actionLeft_triggered() { // 检查是否有选中的项,如果没有选中任何项,则直接返回,不做任何操作 if (!selectModel->hasSelection()) { return; } // 获取当前选中的所有索引 auto indexList = selectModel->selectedIndexes(); // 遍历选中的索引列表 for (auto& index : indexList) { // 根据索引从标准模型中获取对应的项 auto* item = standModel->itemFromIndex(index); // 设置该项的文本对齐方式为左对齐,并垂直方向居中对齐 item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); } } 12、 将表格内的内容居右 // 当用户触发“右对齐”操作时调用此函数 void MainWindow::on_actionRight_triggered() { // 检查是否有选中的项,如果没有选中任何项,则直接返回,不做任何操作 if (!selectModel->hasSelection()) { return; } // 获取当前选中的所有索引 auto indexList = selectModel->selectedIndexes(); // 遍历选中的索引列表 for (auto& index : indexList) { // 根据索引从标准模型中获取对应的项 auto* item = standModel->itemFromIndex(index); // 设置该项的文本对齐方式为右对齐,并垂直方向居中对齐 item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); } } 13、设置字体 // 当用户触发“加粗”操作时调用此函数 void MainWindow::on_actionBold_triggered(bool checked) { // 检查是否有选中的项,如果没有选中任何项,则直接返回,不做任何操作 if (!selectModel->hasSelection()) { return; } // 获取当前选中的所有索引(即用户在界面中选中的单元格) auto indexList = selectModel->selectedIndexes(); // 遍历选中的索引列表 for (auto& index : indexList) { // 根据索引从标准模型中获取对应的项(QStandardItem) auto* item = standModel->itemFromIndex(index); // 获取该项的字体 QFont font = item->font(); // 根据传入的参数 `checked` 设置字体是否加粗 font.setBold(checked); // 将修改后的字体重新设置到该项 item->setFont(font); } } // 当用户触发“斜体”操作时调用此函数 void MainWindow::on_actionItalic_triggered(bool checked) { // 检查是否有选中的项,如果没有选中任何项,则直接返回,不做任何操作 if (!selectModel->hasSelection()) { return; } // 获取当前选中的所有索引 auto indexList = selectModel->selectedIndexes(); // 遍历选中的索引列表 for (auto& index : indexList) { // 根据索引从标准模型中获取对应的项 auto* item = standModel->itemFromIndex(index); // 获取该项的字体 QFont font = item->font(); // 根据传入的参数 `checked` 设置字体是否为斜体 font.setItalic(checked); // 将修改后的字体重新设置到该项 item->setFont(font); } } // 当用户触发“下划线”操作时调用此函数 void MainWindow::on_actionUnderLine_triggered(bool checked) { // 检查是否有选中的项,如果没有选中任何项,则直接返回,不做任何操作 if (!selectModel->hasSelection()) { return; } // 获取当前选中的所有索引 auto indexList = selectModel->selectedIndexes(); // 遍历选中的索引列表 for (auto& index : indexList) { // 根据索引从标准模型中获取对应的项 auto* item = standModel->itemFromIndex(index); // 获取该项的字体 QFont font = item->font(); // 根据传入的参数 `checked` 设置字体是否带有下划线 font.setUnderline(checked); // 将修改后的字体重新设置到该项 item->setFont(font); } }  14、当选择的标签变化时,更新字体种类 // 当选择模型的当前选中项发生变化时调用此函数 void MainWindow::onSelectModelCurrentChanged(const QModelIndex &current, const QModelIndex &previous) { // 检查当前选中的索引是否有效(即是否存在有效的选中项) if (current.isValid()) { // 根据当前选中的索引从标准模型中获取对应的项(QStandardItem) auto* item = standModel->itemFromIndex(current); // 获取该项的字体,并根据字体属性更新界面上的操作按钮状态 // 设置“加粗”操作按钮的状态为字体的加粗属性(true 或 false) ui->actionBold->setChecked(item->font().bold()); // 设置“斜体”操作按钮的状态为字体的斜体属性(true 或 false) ui->actionItalic->setChecked(item->font().italic()); // 设置“下划线”操作按钮的状态为字体的下划线属性(true 或 false) ui->actionUnderLine->setChecked(item->font().underline()); } }  15、运行结果


五、常用接口

以下是 QStandardItemModel 和 QStandardItem 的一些常用方法:

QStandardItemModel 1、设置行列数 : void setRowCount(int rows); void setColumnCount(int columns); 2、插入项: void appendRow(QStandardItem *item); void insertRow(int row, QStandardItem *item); 3、获取项: QStandardItem *item(int row, int column = 0) const; 4、清除模型: void clear();
QStandardItem 1、设置文本: void setText(const QString &text); QString text() const; 2、设置图标: void setIcon(const QIcon &icon); QIcon icon() const; 3、设置子项 : void appendRow(QStandardItem *item); void appendRows(const QList<QStandardItem *> &items); 4、设置用户数据: void setData(const QVariant &value, int role = Qt::UserRole + 1); QVariant data(int role = Qt::UserRole + 1) const;
标签:

QT基础十二、标准项模型:QStandardItemModel由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“QT基础十二、标准项模型:QStandardItemModel