Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access Items stored in a QAbstractListmodel in QML(by delegates) otherwise than using item roles?

Tags:

qt

qml

I just want to display elements from list using QML, but not using item roles. For ex. I want to call a method getName() that returns the name of the item to be displayed.

Is it possible? I didn't find nothing clear reffering to this.

like image 821
Simona B Avatar asked Jan 20 '13 09:01

Simona B


1 Answers

You can use one special role to return the whole item as you can see below:

template<typename T>
class List : public QAbstractListModel
{
public:
  explicit List(const QString &itemRoleName, QObject *parent = 0)
    : QAbstractListModel(parent)
  {
    QHash<int, QByteArray> roles;
    roles[Qt::UserRole] = QByteArray(itemRoleName.toAscii());
    setRoleNames(roles);
  }

  void insert(int where, T *item) {
    Q_ASSERT(item);
    if (!item) return;
    // This is very important to prevent items to be garbage collected in JS!!!
    QDeclarativeEngine::setObjectOwnership(item, QDeclarativeEngine::CppOwnership);
    item->setParent(this);
    beginInsertRows(QModelIndex(), where, where);
    items_.insert(where, item);
    endInsertRows();
  }

public: // QAbstractItemModel
  int rowCount(const QModelIndex &parent = QModelIndex()) const {
    Q_UNUSED(parent);
    return items_.count();
  }

  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
    if (index.row() < 0 || index.row() >= items_.count()) {
      return QVariant();
    }
    if (Qt::UserRole == role) {
      QObject *item = items_[index.row()];
      return QVariant::fromValue(item);
    }
    return QVariant();
  }

protected:
  QList<T*> items_;
};

Do not forget to use QDeclarativeEngine::setObjectOwnership in all your insert methods. Otherwise all your objects returned from data method will be garbage collected on QML side.

like image 190
Pavel Osipov Avatar answered Nov 09 '22 09:11

Pavel Osipov