QStandardItemModel 类作为标准模型,主打“类型通用”,前一篇水文中,老周还没提到树形结构的列表,本篇咱们就好好探讨一下这货。

还是老办法,咱们先做示例,然后再聊知识点。下面这个例子,使用 QTreeView 组件来显示数据,使用的列表模型比较简单,只有一列。

#include <QApplication>
#include <QTreeView>
#include <QStandardItem>
#include <QStandardItemModel> int main(int argc, char* argv[])
{
QApplication app(argc, argv); // 创建组件实例
QTreeView *viewWind = new QTreeView(nullptr);
// 创建数据模型
QStandardItemModel* model;
model = new QStandardItemModel(viewWind);
// 顶级节点
QStandardItem* top1 = new QStandardItem("工程部");
// 添加子节点
top1->setChild(0/*行号*/, new QStandardItem("螺母组"));
top1->setChild(1, new QStandardItem("电钻组")); // 继续添加顶层节点
QStandardItem *top2 = new QStandardItem("情报部");
// 添加子节点
top2->setChild(0, new QStandardItem("偷窥组"));
top2->setChild(1, new QStandardItem("监听组")); // 把两个顶层节点添加到模型中
model->setItem(0/*行号*/, top1);
model->setItem(1, top2);
// 将模型应用到视图
viewWind->setModel(model);
// 显示视图窗口
viewWind->show(); return QApplication::exec();
}

最先添加到 QStandarItemModel 的 QStandardItem 被视为树的顶层节点。调用顶层节点的 setChild 方法会添加子节点。从数据模型的角度看,子节点可以是一个二维表,即可以指定行号和列号的。不过,上面这个示例咱们只用了一列,即列号一直是0,所以调用的重载方法只需指定行号即可。其签名如下:

void setChild(int arow, QStandardItem *aitem)

arow 参数指定的是行的索引,要将子项放在第一行就传 0,放在第二行就传1,等等。此重载版本忽略了列号。

QStandardItem 对象之间建立好层次关系后,最终还要添加到 QStandardItemModel 中的,不然前面的工夫就白做了——数据当然要放进模型中的嘛。

当模型准备好后,调用视图组件的 setModel 方法呈现模型数据。

viewWind->setModel(model);

最终效果可以看下图:

你可能会疑惑:左上角那个“1”是什么鬼?那个鬼是列号,咱们这例子只有一列,所以显示了默认列号。一般单列数据不需要列标题,可以将其隐藏。

viewWind->setHeaderHidden(true);

true 表示隐藏行、列标题,false 表示显示标题。

这样看起来就顺眼多了。

Qt 的 TreeView 有一点很不错,就是可以显示多列。比如,下面这个例子,列表项包含三列。

#include <QApplication>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QTreeView> int main(int argc, char* argv[])
{
QApplication app(argc, argv); // 视图
QTreeView* view = new QTreeView;
// 模型
QStandardItemModel *model = new QStandardItemModel; // 顶层节点1
QStandardItem* root1 = new QStandardItem("普通班");
// 添加子节点
// 第一行
QStandardItem* sub11 = new QStandardItem("230566");
QStandardItem* sub12 = new QStandardItem("小齐");
QStandardItem* sub13 = new QStandardItem("老齐");
root1->setChild(0, 0, sub11);
root1->setChild(0, 1, sub12);
root1->setChild(0,2, sub13);
// 第二行,可以直接插入QStandardItem实例
root1->setChild(1, 0, new QStandardItem("230524"));
root1->setChild(1, 1, new QStandardItem("小王"));
root1->setChild(1, 2, new QStandardItem("隔壁老王"));
// 添加到模型中
model->setItem(0, root1); // 添加顶层节点2
// 可以直接设置,不声明变量
model->setItem(1, new QStandardItem("VIP班"));
// 添加子项
// 第一行
model->item(1, 0)->setChild(0,0,new QStandardItem("2309291"));
model->item(1, 0)->setChild(0,1,new QStandardItem("小曾"));
model->item(1, 0)->setChild(0,2,new QStandardItem("老曾"));
// 第二行
model->item(1, 0)->setChild(1,0,new QStandardItem("2307266"));
model->item(1, 0)->setChild(1, 1,new QStandardItem("小郑"));
model->item(1, 0)->setChild(1,2,new QStandardItem("老郑")); // 顶层节点3
model->setItem(2, new QStandardItem("神童班"));
// 第一行
model->item(2, 0)->setChild(0,0,new QStandardItem("23061685"));
model->item(2, 0)->setChild(0,1, new QStandardItem("小季"));
model->item(2, 0)->setChild(0, 2,new QStandardItem("扯牛堂认证医师老季"));
// 第二行
model->item(2, 0)->setChild(1,0,new QStandardItem("23064217"));
model->item(2, 0)->setChild(1,1,new QStandardItem("小陆"));
model->item(2, 0)->setChild(1,2,new QStandardItem("老陆"));
// 第三行
model->item(2, 0)->setChild(2,0, new QStandardItem("23031982"));
model->item(2, 0)->setChild(2,1,new QStandardItem("小严"));
model->item(2, 0)->setChild(2,2,new QStandardItem("严嵩第11代孙")); // 设置列标题
model->setHorizontalHeaderLabels({"学号", "姓名", "家长代表"});
// 把模型设置到视图
view->setModel(model);
view->setWindowTitle("厚黑幼儿园");
// 显示视图
view->show(); return QApplication::exec();
}

虽然在列表模型中,每个 QStandardItem 都可以把整个二维表作为子节点,而且任意行、列处的项都可以拥有子节点。但是,QTreeView 视图只允许第一列出现折叠效果,所以,对于可折叠的父节点,咱们用一列就可以了,就算设置了多列也没有效果的。不妨想一下,如果每个单元格都可以折叠,那么不仅这控件设计起来困难,而看起来也很混乱,用户没法用了。所以,QTreeView 只认第一列可以折叠。

model 的 setHorizontalHeaderLabels 方法用来设置水平方向上的标题,参数是一个字符串列表。水平方向就是列标题;如果是行标题,就是垂直方向,要调用 setVerticalHeaderLabels 方法。不过,行标题一般不怎么用,顶多显示行号。

最终显示的效果如下:

这个可以显示多列的 TreeView 真的很不错,可惜 .NET 中的 WinForms 和 WPF 自带控件 TreeView 没有这个玩法。

【Qt6】列表模型——树形列表的更多相关文章

  1. 数据库中树形列表(以easyui的tree为例)

    构造一棵easyui前台框架的一个树形列表为例后台框架是spring MVC+JPA. 先看一下数据库是怎么建的,怎么存放的数据 下面是实体类 /** * 部门类 用户所属部门(这里的部门是一个相对抽 ...

  2. Winform开发主界面菜单的动态树形列表展示

    我在之前很多文章里面,介绍过Winform主界面的开发,基本上都是标准的界面,在顶部放置工具栏,中间区域则放置多文档的内容,但是在顶部菜单比较多的时候,就需要把菜单分为几级处理,如可以在顶部菜单放置一 ...

  3. 如何快速开发树形列表和分页查询整合的WInform程序界面

    我在做Winform界面的时候,一般都是统一化处理,界面顶部放置一些字段条件供查询,下面就是分页查询列表,展示相关的数据.但有时候碰到一些表字段内容分类比较多,有一些特别重要,如果放在一个树形列表来进 ...

  4. 如何将数据库中存的树转化为树形列表(以easyui的tree为例)

    很多时候,我们会把一棵树存放到数据库中,当前台需要展示一个树形列表时,将这棵树读取出来并显示,这个过程是怎么实现的呢? 这篇文章是以构造一棵easyui前台框架的一个树形列表为例,后台框架是sprin ...

  5. 在Bootstrap开发框架中使用bootstrapTable表格插件和jstree树形列表插件时候,对树列表条件和查询条件的处理

    在我Boostrap框架中,很多地方需要使用bootstrapTable表格插件和jstree树形列表插件来共同构建一个比较常见的查询界面,bootstrapTable表格插件主要用来实现数据的分页和 ...

  6. Ajax-ajax实例3-动态树形列表

    项目结构: 项目演示: 技术要点: 1.3.2 技术要点在基本原理的介绍中,了解到通过在父节点内动态创建子节点,并利用样式表缩进完成树形列表的基本框架.除了这一点外,还有下面一些问题需要考虑.1 .将 ...

  7. Python操作符重载总结&列表模型

    操作符重载 二元运算符 特殊方法 + __add__,__radd__ - __sub__,__rsub__ * __mul__,__rmul__ / __div__,__rdiv__,__trued ...

  8. 网络采集软件核心技术剖析系列(7)---如何使用C#语言搭建程序框架(经典Winform界面,顶部菜单栏,工具栏,左边树形列表,右边多Tab界面)

    一 本系列随笔概览及产生的背景 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写作和阅读爱好者的喜爱.同时也不乏一些技术爱好者咨询我,这个软件里面各种实用的功能是如何实现的. 该软件 ...

  9. java构建树形列表(带children属性)

    一些前端框架提供的树形表格需要手动构建树形列表(带children属性的对象数组),这种结构一般是需要在Java后台构建好. 构建的方式是通过id字段与父id字段做关联,通过递归构建children字 ...

  10. 【插件篇】前段bootstrap-table-treegrid试手,解决无法显示树形列表或者图标不显示问题。

    说明:具体代码操作我就不贴了.官方有正规的例子!bootstrap-table-examples传送 使用注意事项: 传入的id和pid可以是string类型的(我后台返回的是Long类型转换成str ...

随机推荐

  1. EF Core + MySQL 基本增删改查

    前言 基于EF Core + MySQL的基本增删改查,示例是基于.NET6 + EF Core + MySQL 创建实体和数据库.EFCore 数据迁移项目基础上的内容增加.同时也是对基于Canal ...

  2. ORM总览

    ORM(Object-Relational Mapping)是一种常见的数据访问技术,它将对象模型和关系模型之间进行映射.ORM的主要作用是简化数据访问和管理,提高开发效率和代码质量.在实际应用中,O ...

  3. 如何使用idea来查找所有未使用的代码?

    背景 项目组需要对开发的项目进行一次清理,把一些未被引用的代码清理掉. 我们知道一段代码未被引用,那么代码通常是灰色的. 但是一个完整的项目,会存在成千上万个Java文件,如果一个一个看去需要花费太多 ...

  4. mysql主从-主主架构设计

    前言: 1. mysql主从.主主复制应用场景很多,其原理主推,从定时根据binlog增量拉取更新 2. 如果主/从机器硬件负载过高,或者网络延迟就会造成同步延迟 3. 延迟是必然,mysql复制同步 ...

  5. 记一次 .NET 某埋线管理系统 崩溃分析

    一:背景 1. 讲故事 经常有朋友跟我反馈,说看你的文章就像看天书一样,有没有一些简单入手的dump 让我们先找找感觉,哈哈,今天就给大家带来一篇入门级的案例,这里的入门是从 WinDbg 的角度来阐 ...

  6. 一个高性能、低内存文件上传流.Net组件

    推荐一个用于轻松实现文件上传功能的组件. 项目简介 一个基于 .NET 平台的开源项目,提供了一个简单易用的 API,可以在 Web 应用程序中快速集成文件上传功能. 优化多部分流式文件上传性能:减少 ...

  7. 【小小demo】SpringBoot+Layui登录

    easy-login 基于layui 注册.登录简单实现,并他通过拦截器拦截未登录请求. 项目地址文章末尾 登录拦截器 SystemInterceptor preHandle在 Controller ...

  8. Ubuntu16.04配置NTP时间同步

    环境 查看系统版本:lsb_release -a 名词解释 PDT是指太平洋夏令时(Pacific Daylight Time),是美国西部地区和加拿大的一部分地区使用的时区.它位于UTC-7和UTC ...

  9. JVM运行时数据区之堆空间

    JVM运行时数据区之堆空间 1.核心概述 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域.堆区在JVM 启动的时候即被创建,其空间大小也就确定了,是JVM管理的最大一块内存空间. & ...

  10. ansible 的特点

    ansible的特点 基于Python语言实现 模块化,调用特定的模块,完成特定任务 部署简单,基于python和SSH(默认已安装),yum install 即可,不需要客户端 安全,基于OpenS ...