Question

Je l'ai fait cuire un QAbstractListModel dont les index modèle contiennent un pointeur I absolument nécessaire afin de traiter les données. J'ajoute les données comme ceci:

void PointListModel::addPoint(int frameNumber, QPoint const& pos)
{
    PointItem *pointItem = new PointItem( frameNumber, pos );
    QModelIndex newRow = this->createIndex( m_points.count(), 0, pointItem );

    qDebug() << newRow.internalPointer();

    beginInsertRows( newRow, m_points.count(), m_points.count() );
    m_points.insert( m_points.count( ), pointItem );
    endInsertRows();

    emit pointAdded( pointItem, pos );
}

Ce ne fut que plus tard que je compris que l'argument beginInsertRows demande la parent index de modèle de la nouvelle ligne, et non pas l'indice de modèle réel de la nouvelle ligne.

Alors, à ce moment-ci, Qt m'a donné aucun moyen de fournir un QModelIndex à associer à cette ligne particulière. Comment puis-je créer mon propre index de modèle pour cette nouvelle ligne?

Était-ce utile?

La solution

D'accord, je réécrire ma réponse comme après quelques recherches, j'ai découvert que je me suis trompé.

Vous ne devriez pas faire quelque chose de spécial pour créer un nouvel index lorsque vous ajoutez de nouvelles données. code devrait ressembler à ceci:

PointItem *pointItem = new PointItem( frameNumber, pos );
// assume you insert a top level row, having no parent
beginInsertRows( QModelIndex(), m_points.count(), m_points.count() );
m_points.insert( m_points.count( ), pointItem );
endInsertRows();

Ensuite, vous devez implémenter la méthode index() qui crée un index sur la demande et la méthode parent() qui déterminera le parent d'un indice, mais puisque vous avez un modèle de liste, il devrait probablement toujours juste revenir QModelIndex(). Voici un bon article sur la création de modèles personnalisés .

Voici un exemple complet d'un QAbstractListModel de travail:

class MyModel: public QAbstractListModel {
  Q_OBJECT
  public:
    virtual QModelIndex index(int row, int column = 0,
        const QModelIndex &parent = QModelIndex()) const;
    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    void add(int i);
  private:
    QList<int> list;
};

void MyModel::add(int i)
{
  beginInsertRows(QModelIndex(), list.size(), list.size());
  list.append(i);
  endInsertRows();
}

QModelIndex MyModel::index(int row, int column,
        const QModelIndex &parent) const
{
  return hasIndex(row, column, parent) ? createIndex(row, column, (void*)&list[row])
    : QModelIndex();
}

int MyModel::rowCount(const QModelIndex &parent) const
{
  if (parent.isValid())
    return 0;
  return list.size();
}

QVariant MyModel::data(const QModelIndex &index,
    int role) const
{
  if (!index.isValid())
    return QVariant();
  if (role != Qt::DisplayRole)
    return QVariant();
  return QVariant(QString::number(*static_cast<int*>(index.internalPointer())));
}

Autres conseils

Je l'ai fait cuire un QAbstractListModel dont les index modèle contiennent un pointeur I absolument nécessaire afin de traiter les données.

Si vous commencez avec de mauvaises conditions, vous vous retrouvez avec de mauvaises solutions:)

modèle est assez simple pour que vous n'avez pas besoin de plus que de définir de façon unique le QModelIndex du row() les données les adresses d'index.

Alors, étant donné un QModelIndex de mi, lorsque vous avez fait avant

PointItem * item = static_cast<PointItem*>(mi.internalPointer());

vous pouvez le faire à la place

PointItem * item = plm->pointItemFromIndex(mi);

plm est votre PointListModel. Si vous ne disposez pas d'un pointeur à traîner quand vous avez besoin pour accéder au PointItem, vous pouvez le reconstruire comme ceci:

PointItemModel * plm = qobject_cast<PointItemModel*>(mi.model());
// check for !plm here (!mi.isValid() || qobject_cast fails)

À son tour, PointListMode::pointItemFromIndex() ferait le travail réel:

PointItem * PointListMode::pointItemFromindex(const QModelIndex &mi) const {
    return mi.isValid() ? m_points[mi.row()] : 0 ;
}

Ceci est la chose la plus importante à réaliser lorsque vous travaillez avec QAbstractListModel dans Qt. Mentalement remplacer QModelIndex avec int row, ignorer tout le reste, il a (un QModelIndex non valide a row() == -1)

Même chose pour QAbstractTableModel: réduire mentalement le QModelIndex à int row, int column. Oubliez tout le reste.

La seule fois où vous avez besoin du plein QModelIndex (y compris son internalPointer() ou internalId() est lorsque vous implémentez un modèle d'arbre (de QAbstractItemModel).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top