I’m writing a Qt application to allow the visualization of very heavy data sets.
So, I have a SourceDataModel class, inheriting from QAbstractItemModel that seems to work properly (currently, I only display it in QTableView/QTreeView but later on, I’ll create some custom views).
Now, I would like to be able to filter this data, that is
-
being able to have different data
resolution (i.e. only exposing 1
data item out of 2) -
being able to
apply some filters on the data (i.e.
displaying unix timestamps as
dd/MM/yyyy hh:mm:ss)
So I started to create a ProxySourceDataModel class, which inherits from my SourceDataModel and stores one instance, and basically delegates everything to the instance. From this ProxySourceDataModel, I noticed that no data was displayed when I used it in a QTableView. After some investigation, it seems that it was because i had to forward the signals and slots from the underlying SourceDataModel. No problem, i did it.
But still 2 problems remain, and I can’t figure out how to handle them:
-
I am not able to select the data in the views. If I use the
SourceDataModeldirectly, no problem. But using theProxySourceDataModeli can’t select anything. -
The data is not filtered at all! I overloaded data() in
ProxySourceDataModel, and forward all the other calls to the underlyingSourceDataModel. But still, onlySourceDataModel::data()is called.
Here is some code to illustrate what I’m doing:
class SourceDataModel : public QAbstractItemModel
{
//...
};
class ProxySourceDataModel : public SourceDataModel
{
public:
ProxySourceDataModel(SourceDataModel& model)
: model_(model)
{
// For all QAbstractItemModel's signals emitted by the underlying model,
// I propagate them like this
QObject::connect( &model_, SIGNAL( the_signal()),
this, SLOT (forward_the_signal())) ;
}
slots:
void forward_the_signal()
{
emit the_signal();
}
public:
// For all QAbstractItemModel's virtual function, I do something like this
virtual void the_function()
{
model_.the_function();
}
// This is where I was hoping to do the filtering
virtual QVariant data( const QModelIndex& index,int role=Qt::DisplayRole )
{
return filter( model_.data(index,role) );
}
private:
SourceDataModel& model_;
};
SourceDataModel sourceDataModel;
QTableView view;
view.setModel( new ProxySourceDataModel(sourceDataModel) );
Any help or advice greatly appreciated, thanks for reading!
——————– EDIT ————————
I found it!
The problem was that the view do not use QAbstractItemModel::data() from its model, but rather calls QModelIndex::data() on its items, which in turn calls the QAbstractItemModel::data() of the item’s underlying model.
And since my proxy returned model indexes from the underlying model, that is why the SourceDataModel::data() was always called instead of ProxySourceDataModel()!
I just reimplemented ProxySourceDataModel::index() to return local indexes, and it works like a charm.
Visit In QT, chaining models does not work as expected for more informations.
Thanks!
The problem was that the view do not use
QAbstractItemModel::data()from its model, but rather callsQModelIndex::data()on its items, which in turn calls theQAbstractItemModel::data()of the item’s underlying model.And since my proxy returned model indexes from the underlying model, that is why the
SourceDataModel::data()was always called instead ofProxySourceDataModel()!I just reimplemented
ProxySourceDataModel::index()to return local indexes, and it works like a charm.Visit In QT, chaining models does not work as expected for more informations.