QML学习十六:ListView的简单使用(使用C++ Model)

若该文为原创文章,转载请注明原文出处

一、如何使用C++自定义Model

ListView可以使用C++语言定义的Model,可以从QAbstractItemModel或者QAbstractListModel继承来实现自己的Model类。

具体如何实现?

其实只需要重写rowCount()、data()、rowNames()这三个方法。
对于Qt Quick中的ListView,Delegate通过role-name来访问Model中的数据,当我们在QML中写下Text{text:desc;}这样的Delegate时,意味着将名字为desc的role对应的数据赋值给Text对象的text属性。

如何从desc找到实际的数据

这就要依赖rowNames()函数,QHash<int,QBythArray> roleNames() const 返回一个哈希表,将role与rolename关联起来,当QML中提供role-name时,那么就可以反查到role,进而以查到的role来调用data()方法,就可以获取到实际的数据。

二、例子

工程所使用的是第一个qml工程。

一、创建C++ Model

1、创建文件

 类名:QListModel,继承QAbstractListModel.

 创建完成后,文件会自动生成headerData()、rowCount()、data()等函数。

而我们要做的就是修改这些函数。headerData()函数没什么用,可以删除。

二、修改QlistModel文件

1、创建数据

在QListModel.h中创建 QHash和QList。

在QListModel.cpp中创建数据

2、重写rowCount()、data()、rowNames()

返回QHash数据:

 返回数据长度:

 

 获取数据:

三、C++Model注册

注册相对简单,直接注册就好。

四、QML调用model

 在qml下直接访问

 

 三、完整代码

 1、main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "myobject.h"

#include "QListModel.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    QListModel listModel;
    engine.rootContext()->setContextProperty("QListModel", &listModel);

    engine.load(QUrl(QLatin1String("qrc:/main.qml")));

    return app.exec();
}

2、QListModel.h

#ifndef QLISTMODEL_H
#define QLISTMODEL_H

#include <QAbstractListModel>
#include <QObject>

struct LIST_ITEM_INFO {
    QString qsAnimeName;
    QString qsAnimeLead;
};


class QListModel : public QAbstractListModel
{
    Q_OBJECT

public:
    explicit QListModel(QObject *parent = nullptr);

    // Basic functionality:
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;

    QHash<int,QByteArray> roleNames() const override;

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    Q_INVOKABLE QAbstractItemModel* model();

public:
    enum LIST_ITEM_ROLE
    {
        animeNameRole = Qt::UserRole+1,
        animeLeadRole,
    };

private:
    QList<LIST_ITEM_INFO>           m_date;
    QHash<int,QByteArray>           m_roleName;

};

#endif // QLISTMODEL_H

3、QListModel.cpp

#include "QListModel.h"

QListModel::QListModel(QObject *parent)
    : QAbstractListModel(parent)
{
    m_roleName.insert(animeNameRole, "animeName");
    m_roleName.insert(animeLeadRole, "animeLead");

    m_date = {
        { "vivo", "1200"},
        { "meizu", "1300"},
        { "apple", "1400"},
        { "huawei", "1500"},
    };

}

QHash<int, QByteArray> QListModel::roleNames() const
{
   return m_roleName;
}

int QListModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    return m_date.size();
}

QVariant QListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    switch(role)
    {
    case animeNameRole:
        return m_date.value(index.row()).qsAnimeName;
    case animeLeadRole:
        return m_date.value(index.row()).qsAnimeLead;
    default:
        break;
    }

    return QVariant();
}

QAbstractItemModel *QListModel::model()
{
    return this;
}

4、MyListView.qml

import QtQuick 2.7
import QtQml.Models 2.12



Rectangle {
    id: listViewRct

    width: 400
    height: 300

    ListView {
        id: listView

        anchors.fill: parent
        model: QListModel
        delegate: listViewDelegate
        highlight: Rectangle {
            color: "yellow"
        }
    }

    Component {
        id: listViewDelegate

        Item {
            id: listItem

            width: parent.width
            height: 30
            Text {
                anchors.verticalCenter: parent.verticalCenter
                anchors.left: parent.left
                anchors.leftMargin: 5

                text: qsTr(animeName + ":" + animeLead)
                font.family: "微软雅黑"
                font.pointSize: 12
                color: "#46A4BB"
            }

            MouseArea {
                anchors.fill: parent

                onClicked: {
                    listItem.ListView.view.currentIndex = index;
                }
            }
        }
    }
}

5、main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

Window {
    id: window
    visible: true
    width: 600
    height: 480
    title: qsTr("QML自定义组件")

    Rectangle {
        id: baseRct

        anchors.fill: parent
        color: "lightblue"

        MyListView {
            anchors.centerIn: parent
        }
    }
}

编译结果:

四、总结

自定义model主要是要重写data()等函数,QTableModel、QTableModel调用方法也类似。

如有侵权,请及时联系博主删除,VX:18750903063

  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殷忆枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值