ListView 和C++ QAbstractListModel 自定义model 记录

6 篇文章 0 订阅
test.qml

import QtQuick 2.0
import mylist 1.0

ListView {
    width: 180; height: 200

    model: PeopleListModel {
        id: model1
    }

    delegate: Text {
        text: name + ": " + number
    }

    MouseArea {
        anchors.fill: parent
        onClicked: model1.reload();
    }
    
}

plugin.cpp

#include <QtQml/QQmlExtensionPlugin>
#include <QtQml/qqml.h>
#include <qdebug.h>
#include <qdatetime.h>
#include <qbasictimer.h>
#include <qcoreapplication.h>
#include <QAbstractItemModel>
#include <QStringList>
#include <iostream>


class People {
public:
  People(QString const & name, QString const & number)
    : name_(name), number_(number) {
  }

  QString name() const {
    return name_;
  }

  QString number() const {
    return number_;
  }

private:
  QString name_;
  QString number_;

};

class PeopleListModel : public QAbstractListModel {
  Q_OBJECT

public:
  enum PeopleRoles {
    NameRole = Qt::UserRole + 1,
    NumberRole
  };

  PeopleListModel(QObject * parent = 0)
    : QAbstractListModel(parent) {
    /*
    People p1("Dean", "186***");
    addPeople(p1);

    People p2("Crystal", "186***");
    addPeople(p2);*/
  }

  void addPeople(People const & p) {
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    values_ << p;
    endInsertRows();
  }

  int rowCount(QModelIndex const & parent = QModelIndex()) const {
    return values_.count();
  }

  QVariant data(QModelIndex const & index, int role = Qt::DisplayRole) const {
    std::cout << "data()" << std::endl;
    std::cout << "index row: " << index.row() << " index column: " << index.column() << std::endl;
    if (index.row() < 0 || index.row() >= values_.count()) {
      std::cout << "s1" << std::endl;
      return QVariant();
    }

    People const & p = values_[index.row()];
    std::cout << "role: " << role << std::endl;
    if (role == NameRole) {

      return p.name();
    }
    else if (role == NumberRole) {
      return p.number();
    }
    return QVariant();
  }

  Q_INVOKABLE void reload() {
    std::cout << "--------------------" << std::endl;
    std::cout << "reload()" << std::endl;
    beginResetModel();
    values_.clear();
    endResetModel();
    People p1("Dean", "176***");
    addPeople(p1);

    People p2("Crystal", "176***");
    addPeople(p2);
    std::cout << "values count: " << values_.count() << std::endl;
  }


protected:
  QHash<int, QByteArray> roleNames() const {
    QHash<int, QByteArray> roles;
    roles[NameRole] = "name";
    roles[NumberRole] = "number";
    return roles;
  }

private:
  QList<People> values_;
};

class QExampleQmlPlugin : public QQmlExtensionPlugin {
  Q_OBJECT
  Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtension.PeopleListModel")

  public:
  void registerTypes(char const * uri) {
    qmlRegisterType<PeopleListModel>(uri, 1, 0, "PeopleListModel");
  }
};

//********

当子类化QAbstractListModel时,必须提供rowCount()data()这2个函数的实现,当然也可以提供headerData()函数的实现来使模型表现的更加良好.

如果在QML中使用某模型,或者需要使用超出roleNames()函数包含的默认角色时,必须重载它,也就是必须子类化QAbstractListModel.

当需要链表模型可编辑时,你还必须提供setData()函数的实现,以及提供flags函数的实现以便它返回一个包含Qt::ItemIsEditable的值.

需要注意的一点:QAbstractListModel提供了columnCount()函数的一个默认实现,它会通知视图,该模型中只有一列子项.

模型提供了调整链表数据结构的接口,这可以通过insertRows()removeRows()函数来实现.,当实现这些函数时,最重要的是调用适当的函数,以便所有连接的视图都知道任何更改.

  • 一个insertRows()函数的实现:必须先执行beginInsertRow()函数,然后插入一行新的数据,再然后必须立即执行endInsertRows()函数.
  • 一个removeRows()函数的实现:必须先执行beginRemoveRows()函数,然后再移除一行数据,再然后必须立即执行endRemoveRows()函数.

注意:子类化模型的一些通用准则可以参考Model Subclassing Reference.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

初阳-.-#

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

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

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

打赏作者

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

抵扣说明:

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

余额充值