Frage

Ich habe a gekocht a QAbstractListModel Wessen Modellindizes enthalten einen Zeiger, den ich unbedingt benötigte, um Daten zu verarbeiten. Ich füge die Daten wie SO hinzu:

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

Erst später wurde mir klar, dass das Argument zu beginInsertRows fragt nach dem Elternteil Modellindex der neuen Zeile, nicht der tatsächliche Modellindex der neuen Zeile.

Zu diesem Zeitpunkt hat QT mir keine Möglichkeit gegeben, a zu liefern QModelIndex mit dieser speziellen Reihe zu verknüpfen. Wie erstelle ich meinen eigenen Modellindex für diese neue Zeile?

War es hilfreich?

Lösung

Okay, ich schreibe meine Antwort neu, da ich nach einigen Nachforschungen herausgefunden habe, dass ich es falsch verstanden habe.

Sie sollten nichts Besonderes tun, um einen neuen Index zu erstellen, wenn Sie neue Daten hinzufügen. Ihr Code sollte so aussehen:

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

Dann sollten Sie die implementieren index() Methode, die Indizes bei Bedarf erzeugt und die parent() Methode, die den übergeordneten Index bestimmt, aber da Sie ein Listenmodell haben, sollte es wahrscheinlich immer nur zurückkehren QModelIndex(). Hier ist Ein guter Artikel über das Erstellen benutzerdefinierter Modelle.

Hier ist ein vollständiges Beispiel für eine Arbeit 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())));
}

Andere Tipps

Ich habe ein QabstractListModel gekocht, dessen Modellindizes einen Zeiger enthalten, den ich unbedingt benötigte, um Daten zu verarbeiten.

Wenn Sie mit falschen Anforderungen beginnen, erhalten Sie falsche Lösungen :)

EIN aufführen Modell ist einfach genug, damit Sie nicht mehr als die benötigen QModelIndex's row() So definieren Sie die Daten, die die Index ansprechen.

Also gegeben a QModelIndex mi, als Sie zuvor getan haben

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

Sie können stattdessen tun

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

wo plm ist dein PointListModel. Wenn Sie keinen Zeiger haben, der herumliegt, wenn Sie auf die zugreifen müssen PointItem, Sie können es so rekonstruieren:

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

Im Gegenzug, PointListMode::pointItemFromIndex() würde die tatsächliche Arbeit erledigen:

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

Dies ist das Wichtigste, was man bei der Arbeit mit der Arbeit erkennen kann QAbstractListModel in QT: Mental ersetzen QModelIndex mit int row, ignorieren Sie alles andere, was es hat (einen Invalid QModelIndex hat row() == -1).

Gleiches für QAbstractTableModel: reduzieren die mental die QModelIndex zu int row, int column. Vergiss alles andere.

Das einzige Mal, dass Sie das volle benötigen QModelIndex (einschließlich dessen internalPointer() oder internalId() ist, wenn Sie ein Baummodell implementieren (QAbstractItemModel).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top