Qt reimplement QSortFilterProxyModel :: data () while model uses innerpointer ()

I have a written model (myModel) using internalpointer()

to implement it data()

. I want to filter a tree (based on myModel) with QSortFilterProxyModel

,

I only got it to work when I try to get any data from the tree the application crashes with.

I think this is because when I call the tree data, expecting to get 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()

withinternalpointer()

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 up filter model between myModel ant tree

void myTree::myInit()
{
...
    myModel *model = new myModel();
    proxyModel = new mySortFilterProxyModel(this);
    proxyModel->setSourceModel(model);
    this->setModel(proxyModel);
...

      

myTree is a subclass of QTreeView. I want to use tree->model()

to get the model myModel

how to get the initial data of the model?

+3


source to share


2 answers


This approach will not work with proxy models for the reason you pointed out. Internalpointer / id should only be available in those methods that are guaranteed to pass passed indexes belonging to the model itself, such as data (), etc.

The best approach to get an item for an index is to pass it through 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 when using code:



 const MyItem item = index.data( MyModel::MyItemRole ).value<MyItem>();

      

You will need to specify Q_DECLARE_METATYPE (MyItem) (or MyItem *) in the header and call qRegisterMetaType () at runtime so that MyItem / MyItem * can be passed as a 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 need to know about the proxy.

0


source


All you need to do is call mapToSource () before calling getItem ().

Here, the data () method is used to change the font for a specific type of element. Otherwise, it just calls the data QSortFilterProxyModel ().



virtual QVariant data(const QModelIndex & proxy_index, int role) const
{
    QModelIndex source_index = mapToSource(proxy_index);
    IT::TreeItem * item = IT::toItem(source_index);
    if (role == Qt::FontRole && item->isMessage()) return _bold_font;
    return QSortFilterProxyModel::data(proxy_index, role);
}

      

0


source







All Articles