Domanda

La mia applicazione memorizza i pochi oggetti di un tipo che eredita da QAbstractListModel oggetti.

Questo genera un bel po ' di codice duplicato quando il confezionamento di un semplice std::vector<T> o un QList<T> nel modello con l'aggiunta generale, eliminare e multi-selezione funzionalità.

È questo il modo QAbstractListModel è supposto per essere utilizzato o c'è alcuni adattatore di classe in grado di rimuovere il codice duplicato (almeno per i contenitori che sono parte di Qt)?

Esempio:Vorrei concludere vector<ObjectA> e vector<ObjectB> in un modello.Il codice per insertRows, deleteRows, columnCount ecc.sta andando sempre essere la stessa e vorrei consolidare (con un po ' di meta-programmazione che potrebbe anche lavorare per la con tuple e data).

È stato utile?

Soluzione

È necessario eseguire questa operazione in due classi separate a causa di Qt estensioni c++ (SEGNALI, SLOT, ecc.) non si gioca bene con i modelli.La motivazione e la soluzione alternativa per questo può essere trovato a: http://doc.qt.digia.com/qq/qq15-academic.html

Ecco un abbozzo di soluzione.(Questo è basato sul codice che si sta utilizzando nella nostra applicazione, e che sta lavorando bene.)

1.Elenco astratto classe che fa Qt roba

class FooListModelQt : public QAbstractTableModel {
  Q_OBJECT

public:
  // Non-template methods, signals, slots, etc. can be used here. For example...
  QSet<int> SelectedRows() const;
  // ... etc. ...

signals:
  void SelectionChanged();
  // ... etc. ...

protected:
  explicit FooListModelQt(QObject *parent = NULL);
  virtual ~FooListModelQt() = 0;
  // ... etc. ...

};

2.Classe astratta che fa il modello di roba

template <typename T>
class FooListModel : public FooListModelQt {
public:
  const T* at(int index) const { return items_.at(index); }
  int count() const { return items_.count(); }
  void Append(T *item);
  // ... etc. ...

protected:
  explicit FooListModel(QObject *parent = NULL);
  virtual ~FooListModel();

private:
  QList<T*> items_;
};

3.Elenco effettivo di classe

class BarListModel : public FooListModel<Bar> {
  Q_OBJECT

public:
  explicit BarListModel(QObject *parent = NULL);
  int columnCount(const QModelIndex &parent) const;
  QVariant data(const QModelIndex &index, int role) const;
  // ... etc. ...
};

Altri suggerimenti

Di norma, vorrei implementare il proprio modello di ereditare da QAbstractItemModel direttamente e il mio attuazione per la presentazione di funzioni come data() per gestire i dati del contenitore di stoccaggio io do il modello.

Se si dispone di una duplicazione del codice per l'utilizzo di QList<T> e std::vector<T> allora io suggerirei di conversione da fare:

QList<T> list = QList::fromVector(QVector::fromStdVector(vector));

o in altro modo.

std::vector<T> vector = qlist.toVector().toStdVector();

Mi piacerebbe fare il secondo, ma si può scegliere.

Basato sui vostri ulteriori commenti ci sono 2 percorsi di azione che si può prendere:

Percorso 1:

Implementare objectA e objectB come segue:

class objectA : baseObject

e

class objectB : baseObject

dove baseObject è:

struct baseObject
{
    virtual std::string toString() = 0;
};

Probabilmente più facile da convertire in stringa di qualsiasi altra cosa.

Percorso 2 sarà essenzialmente coinvolgere all'interno del modello utilizzando std::vector<boost::any>() come l'archiviazione dei dati contenitore, in questo modo è possibile implementare un modello unico e la creazione di sottoclassi QAbstractListModel.

La cosa che devi considerare che, se i dati del contenitore di stoccaggio probabilmente si può fare in comune la presentazione dei dati si sono limitati a ciò che si può fare, perché data() funzione che darà vostro punto di vista l'elemento di ritorno QVariant ed è limitata a ciò che si può costruire da.

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