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 SourceDataModel
directly, no problem. But using the ProxySourceDataModel
i can't select anything.
The data is not filtered at all! I overloaded data() in ProxySourceDataModel
, and forward all the other calls to the underlying SourceDataModel
. But still, only SourceDataModel::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 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.