Muy bien, tengo un QStandardItemModel
realmente básico, lleno de algunos números. Logré mostrarlo en un QTableView
, está bien. Creé un nuevo modelo (subclase de QAbstractItemModel
o QAbstractProxyModel
), que es una especie de capa de un modelo existente: es necesario para establecer el modelo de origen, y esta nueva capa debe hacer algunas transformaciones en la real.En QT, los modelos de encadenamiento no funcionan como se esperaba
Mi problema es que en la capa superior, diga "modelo de capa" la función de miembro data(const QModelIndex & index, int role)
nunca se llamó, sin embargo, me gustaría modificar los métodos de visualización por el parámetro de función.
Aquí hay un código de muestra, que demuestra que siempre se llama al modelo original data(index,role)
, mientras que el modelo de capa data(index,role)
nunca. ¿Por qué? ¿Cómo puede el objeto QTableView "saltar" el data(index,role)
de la capa superior?
#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, veo. Tengo entonces 2 preguntas: - ¿Cómo puedo lograr mi objetivo sin crear índices proxy? Me gustaría evitar la creación de índices en el modelo proxy, ya que no habrá filtrado/clasificación, etc., y eso sería una duplicación completa de los índices de los modelos originales. - No veo cómo el 'QSortFilterProxyModel' puede ayudarme. Tengo que codificar la función 'data (..)', y debido a lo anterior, también necesito codificar el 'index (...)' también. ¿Qué 'QSortFilterProxyModel' hace eso' QAbstractProxyModel' no en mi punto de vista? –
Necesita crear nuevos índices que apunten al modelo de proxy. QSortFilterProxyMode crea los índices de proxy para usted. – TimW
¡Muchas gracias, mapToSource y mapFromSource eran los ojos del diablo para mí! Eso funciona como un encanto! –