OK, ho uno QStandardItemModel
veramente semplice, pieno di alcuni numeri. Sono riuscito a visualizzarlo in un QTableView
, va bene. Ho creato un nuovo modello (sottoclasse di QAbstractItemModel
o QAbstractProxyModel
), che è una specie di livello di un modello esistente: è necessario impostare il modello di origine e questo nuovo livello dovrebbe apportare alcune trasformazioni a quello reale.In QT, i modelli di concatenamento non funzionano come previsto
Il mio problema è che nel livello superiore, diciamo "modello di livello", la funzione membro data(const QModelIndex & index, int role)
non viene mai chiamata, tuttavia vorrei modificare i metodi di visualizzazione in base al parametro di ruolo.
Ecco un codice di esempio, che dimostra che il modello originale data(index,role)
viene sempre chiamato, mentre il modello del livello è mai data(index,role)
. Perché? In che modo l'oggetto QTableView "salta" lo data(index,role)
del livello superiore?
#include <QtGui/QApplication> #include <QtGui> #include <QStandardItemModel> class MyModel : public QStandardItemModel { public: MyModel(const int r, const int c, QObject* parent = 0) : QStandardItemModel(r,c,parent) {} QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const { qDebug() << "mymodel data"; return this->itemFromIndex(index)->data(role); } }; class MyProxyModel : public QAbstractProxyModel { public: MyProxyModel(QObject* parent = 0) : QAbstractProxyModel(parent) {} QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const { return this->sourceModel()->index(row,column,parent); } QModelIndex parent (const QModelIndex & index) const { return this->sourceModel()->parent(index); } QModelIndex mapFromSource (const QModelIndex & sourceIndex) const { return sourceIndex; } QModelIndex mapToSource (const QModelIndex & proxyIndex) const { return proxyIndex; } QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const { qDebug() << "myproxymodel data"; return this->sourceModel()->data(index,role); } int rowCount (const QModelIndex & parent = QModelIndex()) const { return this->sourceModel()->rowCount(parent); } int columnCount (const QModelIndex & parent = QModelIndex()) const { return this->sourceModel()->columnCount(parent); } }; int main(int argc, char *argv[]) { QApplication app(argc,argv); MyModel model(8, 2); MyProxyModel mymodel; mymodel.setSourceModel(&model); QTableView tableView; tableView.setModel(&mymodel); tableView.horizontalHeader()->setStretchLastSection(true); for (int row = 0; row < 8; ++row) { for (int column = 0; column < 2; ++column) { QModelIndex index = model.index(row, column, QModelIndex()); model.setData(index, QVariant((row+1) * (column+1))); } } tableView.show(); return app.exec(); }
Ok, vedo. Ho quindi 2 domande: - Come posso raggiungere il mio obiettivo senza creare indici proxy? Mi piacerebbe evitare di creare indici nel modello proxy, perché non ci sarà alcun filtro/ordinamento, ecc. E sarebbe una duplicazione completa degli indici dei modelli originali. - Non vedo come il 'QSortFilterProxyModel' può darmi una mano. Devo codificare la funzione 'data (..)' e, a causa di quanto sopra, ho bisogno anche di codificare 'index (...)'. Cosa 'QSortFilterProxyModel' fa che' QAbstractProxyModel' non è nel mio punto di vista? –
È necessario creare nuovi indici che puntano al modello proxy. QSortFilterProxyMode crea gli indici proxy per te. – TimW
Grazie mille, mapToSource e mapFromSource erano gli occhi del diavolo per me! Funziona come un incantesimo! –