I have a written model (myModel) using internalpointer() for his data() implementation.
I want to filter a tree (based on myModel) using QSortFilterProxyModel,
I got it to work, only when i try to get any data from the tree my app crashes.
I think its because while calling the tree data, expecting to get the myModel indexModel, i get the myQSortFilterProxyModel indexModel.
myItem *myModel::getItem(const QModelIndex &index) const
{
if (index.isValid()) {
myItem *item = static_cast<myItem*>(index.internalPointer());
if (item) return item;
}
return rootItem;
}
myModel data() using internalPointer()
QVariant myModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole && role != Qt::EditRole)
return QVariant();
myItem *item = getItem(index);
return item->data(index.column());
}
setting the filter model between myModel ant the tree
void myTree::myInit()
{
...
myModel *model = new myModel();
proxyModel = new mySortFilterProxyModel(this);
proxyModel->setSourceModel(model);
this->setModel(proxyModel);
...
myTree is QTreeView subclass.
I want to use tree->model() to get myModel model
how do I get the source model data?
This approach won't work with proxy models, for the reason you pointed out. Internalpointer/id should only be accessed in methods that are guaranteed to get indexes passed that belong to the model itself, like data() etc.
A better approach to get an item for an index is pass it via a custom role:
enum Roles {
MyItemRole=Qt::UserRole
};
QVariant data( const QModelIndex& index, int role ) const {
...
if ( role == MyItemRole )
return QVariant::fromValue<MyItem>( item );
//MyItem or MyItem*, depending on whether it can be copied/has
// value semantics or not
...
}
And in using code:
const MyItem item = index.data( MyModel::MyItemRole ).value<MyItem>();
You'll need to Q_DECLARE_METATYPE(MyItem) (or MyItem*) in a header and call qRegisterMetaType() at runtime, so that MyItem/MyItem* can be passed as QVariant.
This approach has the advantage that it will work regardless of any proxy models in between, and the code calling data doesn't even have to know about the proxies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With