【QT】重写QAbstractLIstModel,使用ListView来显示多列数据

这篇具有很好参考价值的文章主要介绍了【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.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")


    ListView {
        anchors.fill: parent;
        model:testModel;
        delegate: Text {
            id: tt
            height:30;
            text: display;//Qt::DisplayRole提供一个角色名display
        }
    }
}

运行结果如下:
【QT】重写QAbstractLIstModel,使用ListView来显示多列数据,QT,QML那些事儿,qt,开发语言
这就是一个列表显示,根据在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.12

Window {
    visible: true
    width: 640
    height: 480
    title: 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,QML那些事儿,qt,开发语言
以上可能还有许多需要完善和修改的地方,后续会跟进修改和优化。需要源码的可以留言邮箱。文章来源地址https://www.toymoban.com/news/detail-664062.html

到了这里,关于【QT】重写QAbstractLIstModel,使用ListView来显示多列数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • wpf中listview内容居中显示

     在WPF中使用ListView经常会用到GridView作为视图,但是却碰到GridViewColumn不能居中对齐的问题, 实现方法 给ListViewItem设置Style,让ListViewItem在水平方向拉伸填充:       Setter Property=\\\"HorizontalContentAlignment\\\" Value=\\\"Stretch\\\"/    ListView ItemContainerStyle=\\\"{StaticResource ListViewItemStyle}\\\"  然后再给

    2024年02月07日
    浏览(34)
  • 使用QT的QML实时显示海康威视网络摄像头的视频数据

    需求背景: 开发的监控软件中有个监控页面需要实时显示网络摄像头的数据,整个监控软件是基于QT的QML语言开发的。在QML中播放视频使用MediaPlayer组件就可以,但网上看到的一些都是播放录制好的视频文件,对于实时播放摄像头数据介绍的比较少。 开发环境: Debian11.3 Qt

    2024年02月09日
    浏览(108)
  • 【QT】QML—— ListView添加固定表头的方法

    在qt中构建界面时经常会对多个数据进行排列显示,可以使用qml提供的ListView组件来快速的构建一个列表模型来进行列表内容的分组显示; 通常的步骤是定义一个简单的ListView列表。创建一个Model并填入数据到其中; 以上的内容在qt运行显示的是一个基础的列表,但是一眼望去

    2024年02月11日
    浏览(43)
  • Qt/QML编程之路:ListView实现横排图片列表的示例(40)

     ListView列表,在QML中使用非常多,排列一个行,一个列或者一个表格,都会用到ListView。 ListView显示从内置QML类型(如ListModel和XmlListModel)创建的模型中的数据,或在C++中定义的从QAbstractItemModel或QAbstract ListModel继承的自定义模型类中的数据。 ListView有一个模型和一个委托,前

    2024年01月25日
    浏览(55)
  • 98.qt qml-使用曲线图综合示例、支持多种鼠标交互、支持百万数据显示(已适配黑白风格)

    在上章我们只是简单实现了曲线图和折线图的显示: 79.qt qml-如何在QML中使用QCustomPlot之曲线/折线示例(已适配黑白风格)_qml 折线图_诺谦的博客-CSDN博客 所以本章实现综合示例、并添加多种功能如下所示: 详细显示:鼠标任意移动显示具体值内容 鼠标右击: 弹出菜单栏,支持

    2024年02月05日
    浏览(62)
  • 使用pandas按列名(标题行内容)读取xls文件指定一列或多列数据

        问题:    在工作中遇到需要一个情况:需要读取xls文件的两个列组成一个列表镶嵌字典的数据供后续使用。     分析: 使用了xlrd只能按列的索引来读取,但是xls文件每次调用都会发生变化,其中不变的是我们要取的那两列的列名一直没变,就是表格的第一行内容会变

    2024年02月12日
    浏览(46)
  • Qt6使用QChartView类与鼠标事件实现波形的缩放、平移、坐标轴单轴缩放与鼠标悬停显示点的数据

            说在前面,本人也是近段时间刚开始学习Qt,实现上述功能的方法可能并不是最优,写此篇文章也是记录下学习的过程,也与大家分享一下。(在此先描述,后面会附上代码)(前面说的会比较基础)         首先,要使用QChartView类得现在.pro文件中加入:(得确保

    2024年02月09日
    浏览(39)
  • Qt中在QLabel上画点,重写QLabel类

    QT中label进行绘图 1.首先新建一个类,让这个类继承QLabel 2.在类中对鼠标点击事件及绘图事件进行重写 3.然后在UI框架下添加label控件, 4.右键label控件,添加重写的类,将其提升为刚刚写好的类 mylabel.h mylabel.cpp

    2024年02月13日
    浏览(43)
  • 【QT多线程一】继承QThread,重写run函数

    Qt有两种多线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类转移到一个Thread里 。 在这里先介绍一下qt多线程的第一种实现方法,继承qthread并重写run函数。 注意 :QThread只有run函数是在新线程里的,其他所有函数都在QThread生成的线程里。如果

    2024年02月14日
    浏览(35)
  • 重写 AppiumService 类,添加默认启动参数,并实时显示启动日志

    在Appium的1.6.0版本中引入了AppiumService类,可以很方便的通过该类来管理Appium服务器的启动和停止。经过测试,使用该类的实例执行关闭server时,并没有释放端口号,会导致第二次启动时失败。另外,使用该类启动server,不能在窗口中实时显示日志,不方便调试。因此,可以重

    2024年02月05日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包