当模型使用internalpointer()时重新实现QSortFilterProxyModel :: data()

时间:2013-01-20 06:27:42

标签: qt

我有一个使用internalpointer()的书面模型(myModel)用于data()实现。 我想使用QSortFilterProxyModel

过滤树(基于myModel)

我得到它的工作,只有当我尝试从树中获取任何数据时,我的应用程序崩溃。

我认为这是因为在调用树数据时,期望获取myModel indexModel,我得到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()使用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());
}

在myModel和树之间设置过滤器模型

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

myTree是QTreeView的子类。 我想使用tree->model()来获取myModel模型

如何获取源模型数据?

2 个答案:

答案 0 :(得分:0)

由于您指出的原因,此方法不适用于代理模型。 只能在保证获取属于模型本身的索引的方法中访问Internalpointer / id,如data()等。

获取索引项目的更好方法是通过自定义角色传递它:

 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
      ...
 }

使用代码:

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

您需要在标头中使用Q_DECLARE_METATYPE(MyItem)(或MyItem *)并在运行时调用qRegisterMetaType(),以便MyItem / MyItem *可以作为QVariant传递。

这种方法的优点是无论中间是否有任何代理模型都能工作,代码调用数据甚至不需要知道代理。

答案 1 :(得分:0)

您需要做的就是在调用getItem()之前调用mapToSource()。

这是我用来更改某种类型项目的字体的data()方法。否则它只调用QSortFilterProxyModel的data()。

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);
}