Вопрос

Я приготовил QAbstractListModel чьи индексы модели содержат указатель, который мне абсолютно нужен для обработки данных. Я добавляю данные так:

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 );
}

Только позже я понял, что аргумент beginInsertRows спрашивает родительский Модельный индекс новой строки, а не фактический индекс модели новой строки.

Итак, на данный момент QT не дал мне никакого способа поставить QModelIndex чтобы связать с этим конкретным рядом. Как создать свой собственный модельный индекс для этой новой строки?

Это было полезно?

Решение

Хорошо, я переписываю свой ответ, так как после некоторого исследования я узнал, что понял это неправильно.

Вы не должны делать ничего особенного, чтобы создать новый индекс при добавлении новых данных. Вы код должен выглядеть так:

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();

Тогда вам следует реализовать index() метод, который создаст индексы по требованию и parent() Метод, который будет определять родитель некоторого индекса, но, поскольку у вас есть модель списка, он, вероятно, всегда должен просто возвращать QModelIndex(). Анкет Вот Хорошая статья о создании пользовательских моделей.

Вот полный пример работы QAbstractListModel:

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())));
}

Другие советы

Я приготовил QabStractListmodel, чьи модельные индексы содержат указатель, который мне абсолютно нужен для обработки данных.

Если вы начнете с неправильных требований, вы получаете неправильные решения :)

А список модель достаточно проста, чтобы вам не нужно больше, чем QModelIndexS. row() Уникально определить данные адреса индекса.

Итак, учитывая QModelIndex mi, когда вы раньше делали

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

вместо этого вы можете сделать

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

куда plm это ваш PointListModel. Анкет Если у вас нет указателя на него, когда вам нужно получить доступ к PointItem, вы можете реконструировать это так:

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

В очереди, PointListMode::pointItemFromIndex() сделает реальную работу:

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

Это самая важная вещь, которую можно понять при работе с QAbstractListModel В QT: мысленно заменить QModelIndex с int row, Игнорируйте все остальное, что у него есть (недействительная QModelIndex имеет row() == -1).

То же самое для QAbstractTableModel: Мысленно уменьшают QModelIndex к int row, int column. Анкет Забудь все остальное.

Единственный раз, когда вам нужен полный QModelIndex (включая его internalPointer() или же internalId() когда вы реализуете модель дерева (QAbstractItemModel).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top