mylistmodel.h
#ifndef MYLISTMODEL_H
#define MYLISTMODEL_H
#include <QAbstractListModel>
class MyListModel : public QAbstractListModel
{
Q_OBJECT
public:
enum ColumnType {
Name,
Value
};
class Data {
friend class MyListModel;
Data(QString name, int value)
: name(name), value(value){}
public:
QString name;
int value;
};
explicit MyListModel(QObject *parent = nullptr);
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int,QByteArray> roleNames() const override;
private:
QList<Data> m_data;
};
mylistmodel.cpp
在模型的实现中最重要的函数是roleNames,为什么可以在QML中直接使用数据对象中的成员的原因就在此处,里面是一个MAP,QML系统根据字段的名称查找数据角色ID,然后时候用这个ID请求模型数据。
#include "mylistmodel.h"
#include <QDebug>
MyListModel::MyListModel(QObject *parent)
: QAbstractListModel(parent)
{
m_data.append({"guomeng", 35});
m_data.append({"wujing", 34});
m_data.append({"guoyuzhen", 14});
}
int MyListModel::rowCount(const QModelIndex &parent) const
{
// For list models only the root node (an invalid parent) should return the list's size. For all
// other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
if (parent.isValid())
return 0;
return m_data.count();
}
QVariant MyListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
qDebug() << __FUNCTION__;
if(role == Name){
return m_data[index.row()].name;
}else if(role == Value){
return m_data[index.row()].value;
}
return QVariant();
}
QHash<int, QByteArray> MyListModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles.insert(Name, "name");
roles.insert(Value, "value");
return roles;
}
注册进QML中
qmlRegisterSingletonInstance("MyModel" ,1, 0, "MyListModel", new MyListModel);
QML中使用
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQml.Models 2.2
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
//import QtQuick.Controls 1.4
import QtQml 2.2
import MyModel 1.0
Window {
visible: true
width: 1280
height: 830
ListView{
id : list
width: 100
height: 300
model: MyListModel
delegate: Text {
id: txt
text: name // 为什么能直接使用name的原因在于,在模型中调用了roleNames函数
}
}
}