QAbstractListModel :: Data()方法永远不会被调用

时间:2019-03-08 21:38:01

标签: c++ qt qml qabstractlistmodel

我正在按照本教程Models and Views: AbstractItemModel Example

的子类 QAbstractListModel 来尝试查看qml中的c ++模型列表。

这是我的实现方式:

项目模型类

class User
{
   private:
     QString m_macAddr;    
     QString m_firstName;    
     QString m_lastName;

 public:
     User();
     User(const QString &mac);
     QString macAddr() const;
     void setMacAddr(QString &mac);
  };
 User::User()
 {}
   User::User(const QString &mac){
     m_macAddr = mac;
  }     
  QString User::macAddr() const{
      return m_macAddr;
  }
  void User::setMacAddr(QString &mac){
      if(mac == m_macAddr)
          return;
       m_macAddr = mac;
  //    emit macAddrChanged();
  }

QAbstractListModel子类

class UserListModel : public QAbstractListModel
{
    Q_OBJECT
public:
    // User model roles
    enum roles{
      macRole = Qt::UserRole + 1
    };
    UserListModel(QObject *parent = nullptr);
QModelIndex index(int row, int column,
                  const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
QModelIndex getIndex(int r, int c, void *p);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    void addUser(const User &user); 
private:
    QList<User> m_users;
protected:
    QHash<int, QByteArray> rolesNames() const;
};
// Class inplementation.

UserListModel::UserListModel(QObject *parent)
: QAbstractListModel(parent)
{

}

void UserListModel::addUser(const User &user){
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    m_users << user;
    endInsertRows();
}

int UserListModel::rowCount(const QModelIndex &parent) const
{
    return m_users.count();
}

QVariant UserListModel::data(const QModelIndex &index, int role) const
{
    if (index.row() < 0 || index.row() >= rowCount())
        return QVariant();
    const User &user = m_users[index.row()];
        if(role == macRole){
            return user.macAddr();
        }
        return QVariant();
    }    
QModelIndex UserListModel::index(int row, int column, const QModelIndex &parent) const
{
    return parent;
}

QModelIndex UserListModel::parent(const QModelIndex &index) const
{
    return index;
}

QModelIndex UserListModel::getIndex(int r, int c, void *p) {
    return this->createIndex(r, c, p);
}
QHash<int, QByteArray> UserListModel::rolesNames() const {
    QHash<int, QByteArray> roles;
    roles[macRole] = "mac";
    return roles;
}

main.cpp

QQmlApplicationEngine engine;
QString mac = "12:3e:3w:4r:33";
userlistModel->addUser(User(mac));
userlistModel->addUser(User(mac));
userlistModel->addUser(User(mac));
userlistModel->addUser(User(mac));
engine.rootContext()->setContextProperty("usersModel", userlistModel);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QModelIndex id = userlistModel->getIndex(1, 0, 0);

QVariant v1 = userlistModel->data(id, Qt::UserRole + 1);

qDebug() << "===========" << v1.toString();
controller::DatabaseService<SqliteDB> *sqliteDb = new controller::DatabaseService<SqliteDB>();
if (engine.rootObjects().isEmpty())
    return -1;
return app.exec();

QML

    ListView{
        id: listView
        anchors.fill: parent
        model:usersModel
        delegate:  Component { HorizontalListItem{mac: mac}}
    }

问题是:

在主函数中,我将4个模型添加到列表模型中,但是它们以qml显示,没有数据。虽然,我正在尝试查看 mac 角色。


我尝试了什么

  • 我尝试在方法 rolesNames() data()中添加断点 但是,似乎编译器没有进入其中的任何一个。
  • 我试图在main函数中调用data()方法,它返回了所需的数据。

1 个答案:

答案 0 :(得分:1)

不必覆盖索引或父方法,也不必创建getIndex方法。在您的情况下,您需要实现roleNames方法:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QAbstractListModel>
#include <QDebug>

class User
{
    QString m_macAddr;
public:
    User(){}
    User(const QString &mac): m_macAddr(mac){}
    QString macAddr() const{return m_macAddr;}
    void setMacAddr(QString &mac){m_macAddr = mac;}
};

class UserListModel : public QAbstractListModel
{
public:
    enum roles{
        macRole = Qt::UserRole + 1
    };
    explicit UserListModel(QObject *parent = nullptr)
        : QAbstractListModel(parent){}
    int rowCount(const QModelIndex &parent = QModelIndex()) const override {
        if (parent.isValid())
            return 0;
        return m_users.count();
    }
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
        if (!index.isValid())
            return QVariant();
        if (index.row() < 0 || index.row() >= rowCount())
            return QVariant();
        const User &user = m_users[index.row()];
        if(role == macRole)
            return user.macAddr();
        return QVariant();
    }
    QHash<int, QByteArray> roleNames() const override{
        QHash<int, QByteArray> roles;
        roles[macRole] = "mac";
        return roles;
    }
    void addUser(const User &user){
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_users << user;
        endInsertRows();
    }
private:
    QList<User> m_users;
};


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

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    UserListModel userlistModel;
    QString mac = "12:3e:3w:4r:33";
    userlistModel.addUser(User(mac));
    userlistModel.addUser(User(mac));
    userlistModel.addUser(User(mac));
    userlistModel.addUser(User(mac));
    QModelIndex ix = userlistModel.index(1, 0);
    QVariant v = userlistModel.data(ix, UserListModel::macRole);
    qDebug() << "===========" << v.toString();
    engine.rootContext()->setContextProperty("usersModel", &userlistModel);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    ListView{
        anchors.fill: parent
        model:usersModel
        delegate: Component
        {
            Text{
                text:  model.mac
            }
        }
    }
}