若该文为原创文章,转载请注明原文出处
一、如何使用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