Qml-Qml中使用自定义QAbstractTableModel

背景:业务中有很多Table表,每个表的内容也不相同,如果针对每个表自定义一个Model的话不太现实,现将Model抽象成通用的,用了两种方法实现。

一、用QList<QVariantList>做数据源

datamodel.h

#ifndef DATAMODEL_H
#define DATAMODEL_H
#include <QObject>
#include <QAbstractItemModel>

class DataModel : public QAbstractTableModel
{
    Q_OBJECT
    Q_PROPERTY(QStringList roles READ roles WRITE setRoles)
public:
    DataModel(QObject *parent = 0);
    ~DataModel();

    //继承基类的函数
    QVariant data(const QModelIndex &index, int role) const;
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QHash<int, QByteArray> roleNames() const; //重新实现roleNames()

    QStringList roles() const;
    void setRoles(const QStringList roles);
signals:
    void dataChanged();
private:
    QList<QVariantList> m_data;
    QStringList m_roleList;
};

#endif // DATAMODEL_H

datamodel.cpp

#include "datamodel.h"
#include <QAbstractTableModel>

DataModel::DataModel(QObject *parent):
    QAbstractTableModel(parent)
{
    QVariantList list1;
    list1.push_back("ceshi1");
    list1.push_back("nan");
    QVariantList list2;
    list2.push_back("ceshi2");
    list2.push_back("nv");
    m_data.push_back(list1);
    m_data.push_back(list2);
}

DataModel::~DataModel()
{

}

int DataModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_data.size();
}

int DataModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    if(m_data.isEmpty())
        return 0;
    return m_data.at(0).size();
}


QVariant DataModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole) {
        return m_data[index.row()].at(index.column());
    }
    else
    {
        int columnIdx = role - Qt::UserRole - 1;
        QModelIndex modelIndex = this->index(index.row(), columnIdx);
        return m_data[modelIndex.row()].at(modelIndex.column());
    }
    return QVariant();
}

QStringList DataModel::roles() const
{
    return m_roleList;
}

void DataModel::setRoles(const QStringList roles)
{
    if(!roles.isEmpty())
    {
        m_roleList = roles;
    }
}

QHash<int, QByteArray> DataModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    for(int i = 0;i < m_roleList.size();i++)
    {
        roles[Qt::UserRole+i+1] = m_roleList.at(i).toLocal8Bit();
    }
    return roles;
}

二、用QList<QMap<QString,QVariant>>做数据源

datamodel.h

#ifndef DATAMODEL_H
#define DATAMODEL_H
#include <QObject>
#include <QAbstractItemModel>

class DataModel : public QAbstractTableModel
{
    Q_OBJECT
    Q_PROPERTY(QStringList roles READ roles WRITE setRoles)
public:
    DataModel(QObject *parent = 0);
    ~DataModel();

    //继承基类的函数
    QVariant data(const QModelIndex &index, int role) const;
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QHash<int, QByteArray> roleNames() const; //重新实现roleNames()

    QStringList roles() const;
    void setRoles(const QStringList roles);
signals:
    void dataChanged();
private:
    QString getKey(int index) const;
private:
    QList<QMap<QString,QVariant>> m_map;
    QStringList m_roleList;
};

#endif // DATAMODEL_H

datamodel.cpp

#include "datamodel.h"
#include <QAbstractTableModel>
DataModel::DataModel(QObject *parent):
    QAbstractTableModel(parent)
{
    QMap<QString,QVariant> map_1;
    map_1.insert("gender","nan");
    map_1.insert("name","ceshi1");
    QMap<QString,QVariant> map_2;
    map_2.insert("name","ceshi2");
    map_2.insert("gender","nv");
    m_map.push_back(map_1);
    m_map.push_back(map_2);
}
DataModel::~DataModel()
{
}
int DataModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_map.size();
}
int DataModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    if(m_map.isEmpty())
        return 0;
    return m_map.at(0).size();
}
QVariant DataModel::data(const QModelIndex &index, int role) const
{
    QString key =  getKey(role);
    return m_map[index.row()].value(key,"####");
}
QStringList DataModel::roles() const
{
    return m_roleList;
}
void DataModel::setRoles(const QStringList roles)
{
    if(!roles.isEmpty())
    {
        m_roleList = roles;
    }
}
QHash<int, QByteArray> DataModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    for(int i = 0;i < m_roleList.size();i++)
    {
        roles[Qt::UserRole+i+1] = m_roleList.at(i).toLocal8Bit();
    }
    return roles;
}
QString DataModel::getKey(int role) const
{
    int columnIndex = role - Qt::UserRole - 1;
    return m_roleList.at(columnIndex);
}

main.cpp

qmlRegisterType<DataModel>("DataModel", 1, 0, "DataModel");

main.qml

import QtQuick 2.0
import QtQuick.Controls 1.4
import DataModel 1.0
Item {
    DataModel {
        id:dataModel
        roles: ["name","gender"]
    }

    TableView {
        anchors.right: parent.right
        model: dataModel
        sortIndicatorVisible:true
        width: 200
        height: 300
        TableViewColumn { role: "name"; title: "Title"; width: 100}
        TableViewColumn { role: "gender"; title: "Gender";width: 100}
    }
}

运行效果


运行效果是一样的,第一种方法和第二种方法的区别在于第一种方法在填装数据的时候必须顺序插入,在获取数据的时候也必须根据行列号获取,第二种方法只需约定好key值,也就是roles,这样填装的时候无需关心顺序

  • 3
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值