【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;}}}}}

以上就是所作的修改,效果图如下:
在这里插入图片描述
以上可能还有许多需要完善和修改的地方,后续会跟进修改和优化。需要源码的可以留言邮箱。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/108152.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习3. 强化学习-Reinforcement learning | RL

强化学习是机器学习的一种学习方式&#xff0c;它跟监督学习、无监督学习是对应的。本文将详细介绍强化学习的基本概念、应用场景和主流的强化学习算法及分类。 目录 什么是强化学习&#xff1f; 强化学习的应用场景 强化学习的主流算法 强化学习(reinforcement learning) …

产品经理的六步路线图:快速制定你的产品计划

2023年的软件世界比以往任何时候都发展得更快&#xff0c;并充满了各种变量。而这将会以各种方式影响产品路线图的落地执行与实现。随着问题越来越多&#xff0c;世界需要不断发展的解决方案。因此&#xff0c;本文结合产品路线图当前存在的共性问题&#xff0c;借鉴企业的成功…

wxpython:wx.html2 是好用的 WebView 组件

wxpython : wx.html2 是好用的 WebView 组件。 wx.html2 是wxPython扩展模块中封装得干净漂亮的模块之一&#xff0c;它被设计为允许为每个端口创建多个后端&#xff0c;尽管目前只有一个可用。它与wx.html.HtmlWindow 的不同之处在于&#xff0c;每个后端实际上都是一个完整的…

图像检索,目标检测map的实现

一、图像检索指标Rank1,map 参考&#xff1a;https://blog.csdn.net/weixin_41427758/article/details/81188164?spm1001.2014.3001.5506 1.Rank1: rank-k&#xff1a;算法返回的排序列表中&#xff0c;前k位为存在检索目标则称为rank-k命中。 常用的为rank1&#xff1a;首…

官方项目《内容示例》中Common UI部分笔记: 1.1 Activatable Widgets

本文主要面向UMG以及Common UI的初学者 文章目录 效果展示概要Activate和Deactivate可见性绑定UI动画设置Common Activatable Widget的默认焦点 效果展示 概要 这个例子非常简单&#xff0c;定义了13个Common Activatable Widget CommonUI_ActivatableWidgets相当于一个容器包…

UITableView自定义TableHeader和TableFooter

UITableView自定义TableHeader和TableFooter 我猜你希望的效果是这样的 我猜你希望的效果是这样的 自定义页眉视图 让我们创建一个文件名 UITableViewHeaderFooterView 的 CustomerHeaderView 子类。 现在让我们创建视图的 Xib 文件并将其命名为 CustomHeaderView。 更改高度标…

第 360 场 LeetCode 周赛题解

A 距离原点最远的点 串中的 “_” 处要么都向左走要么都向右走 class Solution { public:int furthestDistanceFromOrigin(string moves) {int t 0;for (auto x: moves)if (x ! R)t--;elset;int res abs(t);t 0;for (auto x: moves)if (x ! L)t;elset--;res max(res, abs(t…

C语言基础之——指针(下)

前言&#xff1a;本篇文章将继续讲解有关指针的剩余基础知识。 学无止境&#xff0c;一起加油叭&#xff01;&#xff01; 目录 一.指针运算 1.指针 - 整数 2.指针的关系运算 3.指针 - 指针 二.指针与数组 三.二级指针 四.指针数组 总结 一.指针运算 指针运算包括以下三…

可解释性的相关介绍

一、可解释性的元定义&#xff08;Meta-definitions of Interpretability&#xff09; The extent to which an individual can comprehend the cause of a model’s outcome. [1]The degree to which a human can consistently predict a model’s outcome. [2] 可解释性&am…

小研究 - Java虚拟机垃圾收集器的性能分析与调节

垃圾收集器是&#xff2a;&#xff41;&#xff56;&#xff41;虚拟机&#xff08;&#xff2a;&#xff36;&#xff2d;&#xff09;的核心组成部分之一&#xff0c;对&#xff2a;&#xff41;&#xff56;&#xff41;虚拟机的性能有非常重要的影响。本文将介绍&#xff2…

十几款拿来就能用的炫酷表白代码

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 表白代码 1、坐我女朋友好吗&#xff0c;不同意就关机.vbs2、坐我女朋友好吗&…

<八> objectARX开发:动态拖动Jig创建自定义实体

1、介绍 接上一篇文章,在某些情况下,CAD中的实体对象初始参数并不是固定的,我们需要通过jig动态拖动方式来绘制自定义实体,下面就用一个简单的例子来介绍一下自定义实体动态绘制。   实体形状:包括实体夹点和文字夹点拖动实现。 2、效果 3、源码 static void RYMyGrou…

CAN总线学习——物理层、数据链路层、CANopen协议

1、CAN总线介绍 1.1、CAN总线描述 (1)CAN总线支持多节点通信&#xff0c;但是节点不分区主从&#xff0c;也就是不存在一个节点来负责维护总线的通信&#xff1b;这点可以和I2C总线对对比&#xff0c;I2C是一主多从模式&#xff1b; (2)是差分、异步、串行总线&#xff0c;采用…

华为OD机试 - 求满足条件的最长子串的长度 - 双指针(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

无人驾驶领域的软件测试该如何开展?

无人驾驶汽车使用自主决策和控制系统&#xff0c;这种系统通常由多个软件和硬件组件组成。软件测试是必要的&#xff0c;因为它可以确保无人驾驶汽车的软件系统达到高度可靠性和安全性&#xff0c;以及提高无人驾驶汽车的性能和可靠性。 因此无人驾驶汽车是一定要进行严格的软件…

关于类的隐形生成函数

https://www.youtube.com/watch?ve8Cw17p_BiU&listPL5jc9xFGsL8FWtnZBeTqZBbniyw0uHyaH&index6 https://www.youtube.com/watch?vKMSYmY74AEs&listPLE28375D4AC946CC3&index4 如果只有copy asignment operator, 那么default construct will be generated as…

PyCharm软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 PyCharm是一种集成开发环境&#xff08;IDE&#xff09;&#xff0c;专门为Python开发者设计。它是由捷克软件公司JetBrains开发的&#xff0c;为Python开发人员提供了高效、易用和功能丰富的工具集。 以下是PyCharm软件的主要…

【C语言】操作符大全(保姆级介绍)

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;C语言 &#x1f525;该篇将详细介绍各种操作符的功能。 目录&#xff1a; &#x1f4d8; 前言① 算术操作符②移位操作符③位操作符④赋值操…

JS-this知识点、面试题

一、this指向什么 1.简介 2.规则一&#xff1a;默认绑定 3.规则二&#xff1a;隐式绑定 4.规则四&#xff1a;new绑定 5.规则三&#xff1a;显式绑定 call、apply、bind 6.内置函数的绑定 7.规则优先级 8.this规则之外--es6剪头函数 9.ES6剪头函数this 二、This面试题 面试题…

解决Spring Boot项目中pom.xml环境配置 打包后生效 但idea版本运行无效的问题

上文 Spring Boot中通过maven进行多环境配置 中我们通过pom.xml配置了环境选择 但这个只有在打包出来的jar中生效 我们直接通过 idea启动 这个东西确实是有点问题 其实 我们执行一下 compile 手工编译一下 然后重新启动 很明显 我们这里配置就已经生效了 这个就是 我们每次…