Domanda

Ho cucinato un QAbstractListModel cui indici modello contenere un puntatore Sono assolutamente necessario al fine di elaborare i dati. Aggiungo i dati in questo modo:

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

E 'stato solo più tardi che mi sono reso conto che l'argomento a beginInsertRows sta chiedendo per il genitori Indice di modello della nuova riga, non indice di modello reale della nuova riga.

Quindi, a questo punto nel tempo, Qt mi ha dato modo di fornire un QModelIndex da associare a questa particolare riga. Come faccio a creare il mio indice di modello di questa nuova riga?

È stato utile?

Soluzione

Va bene, sto riscrivendo la mia risposta come dopo alcune ricerche ho scoperto che mi sono sbagliato.

Non si dovrebbe fare nulla di speciale per creare un nuovo indice quando si aggiungono nuovi dati. Si codice dovrebbe essere simile a questo:

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

Poi si dovrebbe implementare il metodo index() che creerà indici su richiesta e il metodo parent() che determinerà il genitore di qualche indice, ma dal momento che si dispone di un modello di lista, si dovrebbe probabilmente sempre e solo tornare QModelIndex(). Ecco un buon articolo sulla creazione di modelli personalizzati .

Ecco un esempio completo di un QAbstractListModel di lavoro:

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

Altri suggerimenti

Ho cucinato un QAbstractListModel cui indici modello contenere un puntatore Sono assolutamente necessario al fine di elaborare i dati.

Se si inizia con i requisiti sbagliate, si finisce con soluzioni sbagliate:)

A modello è abbastanza semplice in modo che non avete bisogno di più di QModelIndex del row() per definire i dati in modo univoco gli indirizzi di indice.

Quindi, dato un QModelIndex mi, quando prima di fatto

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

si può invece fare

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

dove è il vostro plm PointListModel. Se non si dispone di un puntatore ad esso in giro quando è necessario accedere al PointItem, è possibile ricostruire in questo modo:

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

A sua volta, PointListMode::pointItemFromIndex() farebbe il lavoro effettivo:

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

Questa è la cosa più importante da capire quando si lavora con QAbstractListModel in Qt:. Mentalmente sostituire QModelIndex con int row, ignora tutto il resto è (un QModelIndex invalido ha row() == -1)

Lo stesso per QAbstractTableModel: ridurre mentalmente il QModelIndex a int row, int column. Dimenticate tutto il resto.

L'unica volta che è necessario il pieno QModelIndex (compresa la sua internalPointer() o internalId() è quando si implementa un modello ad albero (QAbstractItemModel).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top