3

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

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

我认为这是因为在调用树数据时,期望得到 myModel indexModel,我得到了myQSortFilterProxyModelindexModel。

myItem *myModel::getItem(const QModelIndex &index) const
{
    if (index.isValid()) {
        myItem *item = static_cast<myItem*>(index.internalPointer());
        if (item) return item;
    }
    return rootItem;
}

我的模型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 模型

如何获取源模型数据?

4

2 回答 2

1

由于您指出的原因,这种方法不适用于代理模型。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 传递。

这种方法的优点是无论中间有任何代理模型,它都可以工作,并且调用数据的代码甚至不必知道代理。

于 2013-01-20T23:20:16.340 回答
1

您所要做的就是在调用 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);
}
于 2013-06-18T16:22:42.150 回答