【QT】重写QAbstractLIstModel,使用ListView来显示多列数据
qt提供了几个视图来进行信息的列表显示,QListView可以用来显示继承QStractListModel的字符串列表中的字符串,默认的模型里面只包含一列的内容:
这里以qml为例子,先新建一个qml的项目,示例代码如下:
先创建一个列表的只读模型,以QAbstractListModel为基类,最基础的只用实现两个函数即可:rowCount()和
data(),一个用来返回模型的行数,一个用来返回指定的模型索引的数据项:
//返回模型的行数int rowCount(const QModelIndex &parent = QModelIndex()) const;//返回指定模型索引的数据项QVariant data(const QModelIndex &index, int role) const;
使用一个QStringList列表来作为内部的数据源:
QStringList m_strValue;
现在来开始实现这两个函数:这两个函数的实现是比较简单的
int MyListModel::rowCount(const QModelIndex &parent) const
{Q_UNUSED(parent);return m_strValue.count();
}QVariant MyListModel::data(const QModelIndex &index, int role) const
{if(!index.isValid())return QVariant();if(role == Qt::DisplayRole)return m_strValue.at(index.row());return QVariant();
}
再建立一个设置改列表值的函数,因为后面要将测试的model注册到qml中去,所以不方便再构造函数中将QStringList的值设置下去,所以这里添加一个setDataModel()函数,函数的定义如下:
void MyListModel::setDataModel(const QStringList &var)
{if(var.isEmpty())return ;m_strValue = var;
}
到这里对MyListModel的类的完善已经差不多了,接下来新增一个测试的类来添加数据到列表中去:
这里直接给出,两个文件如下:
testlistmodel.h
#ifndef TESTLISTMODEL_H
#define TESTLISTMODEL_H#include <QObject>
#include "mylistmodel.h"class TestListModel : public QObject
{Q_OBJECT
public:explicit TestListModel(QObject *parent = nullptr);MyListModel m_model;signals:};#endif // TESTLISTMODEL_H
testlistmodel.cpp
#include "testlistmodel.h"TestListModel::TestListModel(QObject *parent) : QObject(parent)
{QStringList list;for(int i = 0; i < 30; i++){list << QString("第%1个").arg(i);}m_model.setDataModel(list);
}
最后再main.cpp中将model注册到qml中:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "testlistmodel.h"int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QQmlApplicationEngine engine;TestListModel model;engine.rootContext()->setContextProperty("testModel", &model.m_model);const QUrl url(QStringLiteral("qrc:/main.qml"));QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);engine.load(url);return app.exec();
}
接下来在qml中使用ListView组件,并指定使用的model就可以了。
main.qml如下:
import QtQuick 2.12
import QtQuick.Window 2.12Window {visible: truewidth: 640height: 480title: qsTr("Hello World")ListView {anchors.fill: parent;model:testModel;delegate: Text {id: ttheight:30;text: display;//Qt::DisplayRole提供一个角色名display}}
}
运行结果如下:

这就是一个列表显示,根据在c++中提供的数据注册到qml中来显示的,动图这里就不展示了。
可以看到这里显示的是一列的内容,如果要使用ListView来显示多列的内容,应该如何去设计model呢?这里就需要去修改数据类型,也就是不能继续用QStringList作为存储数据的了,需要重新设计一个数据类型可以去报存多个数据:这里选取的数据类型如下:
QMap<int, QMap<int,QVariant>> tmp; //使用QMap来存存放数据,内嵌一个QMap来存放每一行的各个列的数据
//内嵌的QMap也可单独设计一个类来实现,只不过在后续的其他方面也需要做不同的修改,这里先不说
定义一个这样的容器来做数据的存放,还要在原有的基础上添加几个函数,也要重写roleNames()函数,如下:
再新增一个变量,用来存放角色role:
QHash<int, QByteArray> m_roleName();
后面直接放上修改后的文件,改的内容比较多,直接在代码中标注出来:
mylistmodel.h
#ifndef MYLISTMODEL_H
#define MYLISTMODEL_H#include <QObject>
#include <QAbstractListModel>class MyListModel : public QAbstractListModel
{Q_OBJECT
public:MyListModel(QObject *parent = 0);//返回模型的行数int rowCount(const QModelIndex &parent = QModelIndex()) const;//返回指定模型索引的数据项QVariant data(const QModelIndex &index, int role) const;//设置模型数据void setDataModel(const QMap<int, QMap<int, QVariant>> &var);//返回列int columnCount(const QModelIndex &parent = QModelIndex()) const;QHash<int, QByteArray> roleNames() const;void insertRoleName(const int role, const QByteArray name);private:QStringList m_strValue;QMap<int, QMap<int, QVariant>> m_map;QHash<int, QByteArray> m_roleName;};#endif // MYLISTMODEL_H
mylistmodel.cpp
#include "mylistmodel.h"MyListModel::MyListModel(QObject* parent) : QAbstractListModel(parent)
{}int MyListModel::rowCount(const QModelIndex &parent) const
{Q_UNUSED(parent);return m_map.count();//改为m_map
}QVariant MyListModel::data(const QModelIndex &index, int role) const
{if(!index.isValid())return QVariant();if(index.row() >= m_map.size())return QVariant();if(role >= Qt::UserRole) //使用QT提供的自定义的角色的值,累加{QMap<int, QVariant> var = m_map.value(index.row());return var.value(role);}return QVariant();
}void MyListModel::setDataModel(const QMap<int, QMap<int, QVariant>> &var)
{if(var.isEmpty())return ;m_map = var;
}int MyListModel::columnCount(const QModelIndex &parent) const
{Q_UNUSED(parent);return m_roleName.count();
}QHash<int, QByteArray> MyListModel::roleNames() const
{return m_roleName;
}void MyListModel::insertRoleName(const int role, const QByteArray name)
{m_roleName.insert(role, name);
}
testlistmodel.cpp
#include "testlistmodel.h"TestListModel::TestListModel(QObject *parent) : QObject(parent)
{QMap<int, QMap<int, QVariant>> var;for(int i = 0; i < 30; i++){QMap<int,QVariant> map;map.insert(Qt::UserRole,QString("第%1个").arg(i));map.insert(Qt::UserRole+1,QString("产品%1个").arg(i));var.insert(i,map);}m_model.setDataModel(var);//添加角色m_model.insertRoleName(Qt::UserRole,"Column_One");m_model.insertRoleName(Qt::UserRole+1,"Column_Two");}
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12Window {visible: truewidth: 640height: 480title: qsTr("Hello World")ListView {anchors.fill: parent;model:testModel;delegate: Item {id: it;height:30;width:parent.width;Row {anchors.fill: parent;Text{width:parent.width/2;text: Column_One;}Text {width:parent.width/2;text: Column_Two;}}}}}
以上就是所作的修改,效果图如下:

以上可能还有许多需要完善和修改的地方,后续会跟进修改和优化。需要源码的可以留言邮箱。
相关文章:
【QT】重写QAbstractLIstModel,使用ListView来显示多列数据
qt提供了几个视图来进行信息的列表显示,QListView可以用来显示继承QStractListModel的字符串列表中的字符串,默认的模型里面只包含一列的内容: 这里以qml为例子,先新建一个qml的项目,示例代码如下: 先创建一…...
【从零学习python 】64. Python正则表达式中re.compile方法的使用详解
文章目录 re.compile方法的使用进阶案例 re.compile方法的使用 在使用正则表达式时,我们可以直接调用re模块的match、search、findall等方法,并传入指定的正则表达式进行匹配。另外,我们还可以使用re.compile方法生成一个正则表达式对象&…...
【FAQ】视频云存储/安防监控EasyCVR视频汇聚平台如何通过角色权限自行分配功能模块?
视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、…...
基于Spring Boot的社区诊所就医管理系统的设计与实现(Java+spring boot+MySQL)
获取源码或者论文请私信博主 演示视频: 基于Spring Boot的社区诊所就医管理系统的设计与实现(Javaspring bootMySQL) 使用技术: 前端:html css javascript jQuery ajax thymeleaf 微信小程序 后端:Java …...
mysql从传统模式切到GTID模式后启动主从,主从异常报错1236
一 前言 MySQL 的主从复制作为一项高可用特性,用于将主库的数据同步到从库,在维护主从复制数据库集群的时候,作为专职的MySQL DBA,笔者相信大多数人都会遇到“Got fatal error 1236 from master when reading data from binary …...
Qt+C++串口调试接收发送数据曲线图
程序示例精选 QtC串口调试接收发送数据曲线图 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对<<QtC串口调试接收发送数据曲线图>>编写代码,代码整洁,规则&…...
【从零学习python 】75. TCP协议:可靠的面向连接的传输层通信协议
文章目录 TCP协议TCP通信的三个步骤TCP特点TCP与UDP的区别TCP通信模型进阶案例 TCP协议 TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议…...
IPv4 基础概念
IPv4 基础概念 IPv4 广播地址 广播是一种通信方式,用于将数据包发送到同一网络中的所有设备。在广播中,数据包被发送到特殊的广播地址,例如在IPv4中,广播地址通常为特定子网的广播地址(例如,192.168.1.0/…...
stm32片内读写项目总结(多字节读写tongxindu)
1.flash操作驱动程序 a头文件 #ifndef FLASH_H #define FLASH_H #include “stm32f4xx.h” #define BOARD_NUM_ADDR 0x0800C000 #define STM32_FLASH_BASE 0x08000000 //STM32 FLASH的起始地址 #define FLASH_WAITETIME 50000 //FLASH等待超时时间 //FLASH 扇区的起始地址…...
ECMAScript6 简介及拓展
ECMAScript简介 JavaScript是大家所了解的语言名称, 但它的正式名称叫做ECMAScript。 1996年11月, JavaScript的创造者网景公司将JavaScript提交给国际化组织 ECMA(欧洲计算机制造联合会), 希望这种语言能够成为国际标准。 随后 ECMA 发布…...
可视化构建包分析报告
一、webpack 使用 webpack-bundle-analyzer 插件即可。 安装:npm install webpack-bundle-analyzer -D 使用:new BundleAnalyzerPlugin(options?: object) Name Type Description analyzerMode One of: server, static, json, disabled Default: se…...
统一git使用方法,git状态变迁图,git commit提交规范
目录 说明 统一git使用方法 git状态变迁图 git commit 提交规范 说明 多次工作中多名员工不懂git多次技术分享,自行查资料学习git并使用,会出现使用各种偏僻的命令,异常问题无法解决;或出现带url的git合并提交。主要是学的不…...
react与vue的区别
React和Vue.js是两个流行的JavaScript库/框架,用于构建用户界面。以下是React和Vue之间的一些主要区别: 学习曲线:Vue.js对于新手来说比React更容易学习和上手。 构建方式:React强调组件的可重用性,而Vue.js更注重模板…...
成功解决SQL 错误 [22000]: 第3 行附近出现错误: 试图修改自增列[ID](达梦数据库)
当我们使用工具来手动修改自增列的自增ID时,可能会报如下异常 SQL 错误 [22000]: 第3 行附近出现错误:试图修改自增列[ID] 解决办法: 可以使用SQL语句来修改 ALTER TABLE "fdw"."SYSTEM_DICT_TYPE" DROP IDENTITY; UPDATE "f…...
【算法】活用双指针完成复写零操作
Problem: 1089. 复写零 文章目录 题目解析算法原理分析找到最后一个复写的位置从后往前进行复写操作 代码展示 题目解析 首先我们来分析一下本题的题目意思 可以看到题目中给到了一个数组,意思是让我们将数组中的零元素都复写一遍,然后将其余的元素向后平…...
【面试高频题】难度 3/5,字典树热门运用题
题目描述 这是 LeetCode 上的 「745. 前缀和后缀搜索」 ,难度为 「困难」。 Tag : 「字典树」 设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。 实现 WordFilter 类: WordFilter(string[] words) 使用词典中的单词 words 初…...
vue base64图片转file流 下载到本地 或者上传
<img :src"data:image/png;base64,form.img" style"max-width:280px;max-height: 280px;margin: auto;" />// base64 转file const base64ToFile()>{let byImg atob(form.img); // 解码base64let n byImg.lengthlet a new Uint8Array(n);while…...
无涯教程-PHP - 简介
PHP 7是最期待的,它是PHP编程语言的主要功能版本。 PHP 7于2015年12月3日发布。本教程将以简单直观的方式教您PHP 7的新功能及其用法。 无涯教程假设您已经了解旧版本的PHP,现在就可以开始学习PHP 7的新功能。 使用下面的示例- <html><head&…...
web基础+HTTP协议+httpd详细配置
目目录录 一、Web基础1.1 HTML概述1.1.1 HTML的文件结构1.1.2 HTML中的部分基本标签 1.3 MIME1.4 URI 和 URL1.4 定义1.4.2 URI 和 URL 的区别 二、静态资源和动态资源2.1 静态资源2.2 动态资源 三、HTTP协议3.1 HTTP协议简介3.2 HTTP协议版本3.2 HTTP方法3.3 HTTP请求访问的完…...
【sql】MongoDB的增删改查分页条件等
【sql】MongoDB的增删改查分页条件等 //增 //新增数据2种方式 db.msg.save({"name":"springboot😀"}); db.msg.insert({"name":"mango good"}); db.msg.save({"name":"springboot",type:"工具书&…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
倒装芯片凸点成型工艺
UBM(Under Bump Metallization)与Bump(焊球)形成工艺流程。我们可以将整张流程图分为三大阶段来理解: 🔧 一、UBM(Under Bump Metallization)工艺流程(黄色区域ÿ…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...
